Find undeclared namespace'prefix - c#

I'd like to retrieve each undeclared namespaces' prefix in a Xml file on load using (where msCurrentContent is a memorystream) :
xmlCurrentDoc = new XmlDocument();
xmlCurrentDoc.Load(msCurrentContent);
For example, when loading a Xml file with the following declaration :
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="mondoc" xls:schemaLocation="mondoc.xsd">
It must retrieve the undeclared prefix xls without throwing an exception (as it does know).
What is the best way to do this ?
Thanks for your help !

This is really hacky, but you could subclass XmlNamespaceManager and add fake namespaces as you encounter unknown prefixes:
public class MyXmlNamespaceManager : XmlNamespaceManager
{
const string DefaultMissingNamespacePrefix = "http://missing.namespace.prefix.net/2014/";
private string MissingNamespacePrefix { get; set; }
private int NextMissingNamespaceIndex { get; set; }
// The dictionary consists of a collection of namespace names keyed by prefix.
public Dictionary<string, List<string>> MissingNamespaces { get; private set; }
public MyXmlNamespaceManager(XmlNameTable nameTable)
: this(nameTable, null) { }
public MyXmlNamespaceManager(XmlNameTable nameTable, string missingNamespacePrefix)
: base(nameTable)
{
this.MissingNamespacePrefix = (string.IsNullOrEmpty(missingNamespacePrefix) ? DefaultMissingNamespacePrefix : missingNamespacePrefix);
this.MissingNamespaces = new Dictionary<string, List<string>>();
}
void AddMissingNamespace(string prefix)
{
if (string.IsNullOrEmpty(prefix))
return;
string uri;
do
{
int index = NextMissingNamespaceIndex++;
uri = MissingNamespacePrefix + index.ToString();
}
while (LookupPrefix(uri) != null); // Just in case.
Debug.WriteLine(string.Format("Missing namespace \"{0}\" found, added fake namespace \"{1}\"", prefix, uri));
AddNamespace(prefix, uri);
MissingNamespaces.Add(prefix, uri);
}
public override bool HasNamespace(string prefix)
{
var result = base.HasNamespace(prefix);
if (!result)
AddMissingNamespace(prefix);
result = base.HasNamespace(prefix);
return result;
}
public override string LookupNamespace(string prefix)
{
var result = base.LookupNamespace(prefix);
if (result == null)
AddMissingNamespace(prefix);
result = base.LookupNamespace(prefix);
return result;
}
}
public static class DictionaryExtensions
{
public static void Add<TKey, TValue>(this IDictionary<TKey, List<TValue>> listDictionary, TKey key, TValue value)
{
if (listDictionary == null)
throw new ArgumentNullException();
List<TValue> values;
if (!listDictionary.TryGetValue(key, out values))
{
listDictionary[key] = values = new List<TValue>();
}
values.Add(value);
}
}
And then, to test:
string xml = #"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""no""?>
<Document xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""mondoc"" xls:schemaLocation=""mondoc.xsd"">
</Document>
";
XmlDocument xmlDoc;
using (var stream = new StringReader(xml))
{
var settings = new XmlReaderSettings();
settings.NameTable = new NameTable();
var manager = new MyXmlNamespaceManager(settings.NameTable);
XmlParserContext context = new XmlParserContext(null, manager, null, XmlSpace.Default);
using (var xmlReader = XmlReader.Create(stream, settings, context))
{
xmlDoc = new XmlDocument();
xmlDoc.Load(xmlReader);
}
}
string newXml;
using (var writer = new StringWriter())
{
xmlDoc.Save(writer);
newXml = writer.ToString();
}
Debug.WriteLine(newXml);
Which produces the following result:
<?xml version="1.0" encoding="utf-16" standalone="no"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="mondoc" xls:schemaLocation="mondoc.xsd" xmlns:xls="http://missing.namespace.prefix.net/2014/0">
</Document>
At least, it's not an exception. Note - only partially tested.

Related

Create/delete element on XMLNode c#

It's my fist time working with XML and I use a basic XML file format like this:
<root>
<staff id="1">
<name>name 1</name>
<phone>123456</phone>
</staff>
<staff id="2">
<name>name 2</name>
<phone>123789</phone>
<phone2>123789</phone2>
</staff>
</root>
some nodes have more elements (phone2 in this case). I want to add (or remove) an element on a node. I'm creating a WinForms in C# that work with this XML. I'm doing:
I read the XML to have a XmlNodeList variable.
From XmlNodeList I get the node that I want modify to a XmlNode variable.
I modify name or phone on XmlNode
I read again the XML file and I update the correct node with the XmlNode variable new info.
My problem is I don't know how add (or remove) the element "phone2" on my XmlNode variable.
program.cs:
public static XmlNode staff;
public static XmlNodeList xnList = GetList();
public static XmlNodeList GetList()
{
XmlNodeList xnList;
XmlDocument doc = new XmlDocument();
doc.Load(path);
xnList = doc.SelectNodes("/root/staff");
return xnList;
}
public static void GetID(string id)
{
foreach (XmlNode xn in xnList)
{
if(xn.Attributes["id"].Value == id)
{
staff = xn;
}
}
}
form1.cs
private void btnOK_Click(object sender, EventArgs e)
{
Program.staff["name"].InnerText = textBoxName.Text;
Program.staff["phone"].InnerText = textBoxPhone.Text;
if (Program.staff.SelectSingleNode("phone2") == null)
{
// here I want to create "phone2" in Program.staff if not exist
// to update XML file later.
Program.staff["phone2"].InnerText = textBoxPhone2.Text;
}
}
I don't find the correct method to do it and maybe it's not the best way to do it, but I accept suggestions...
There are multiple ways to work with XML files. I'll show two options below.
Test.xml:
<root>
<staff id="1">
<name>Name 1</name>
<phone>123456</phone>
</staff>
<staff id="2">
<name>Name 2</name>
<phone>123457</phone>
<phone>123458</phone>
</staff>
</root>
Option 1 (LINQ to XML):
Add the following using directive:
using System.Xml.Linq;
CreateXmlLinq:
private void CreateXmlLinq(string filename)
{
XElement root = new XElement("root",
new XElement("staff", new XAttribute("id", "1"),
new XElement("name", "Name 1"),
new XElement("phone", "123456")),
new XElement("staff", new XAttribute("id", "2"),
new XElement("name", "Name 2"),
new XElement("phone", "123457"),
new XElement("phone", "123458"))
);
root.Save(filename);
}
Usage:
using (SaveFileDialog sfd = new SaveFileDialog())
{
sfd.Filter = "XML File (*.xml)|*.xml";
sfd.FileName = "Test.xml";
if (sfd.ShowDialog() == DialogResult.OK)
{
//save to file
CreateXmlLinq(sfd.FileName);
Debug.WriteLine($"Info: Saved to {sfd.FileName}");
}
}
To remove phone number 123458 where staff id = 2:
RemovePhone:
private void RemovePhone(string filename, string id, string phoneNumber)
{
//load from file
XElement root = XElement.Load(filename);
//remove specified phone number
root.Elements("staff").Where(s => s.Attribute("id").Value == id).Elements("phone").Where(p => p.Value == phoneNumber).Remove();
//save to file
root.Save(filename);
}
Option 2 (XML Serialization):
For this approach, we'll use nested classes.
Add the following using directives to each of the classes:
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
You can name the classes whatever you like, I've chosen to prepend the word "Xml". Additionally for the nested classes, I've chosen to append the ancestors' names. In this case, there is only one ancestor (the parent) "root".
XmlRoot
XmlRootStaff: ("XmlRoot" + "Staff)
XmlRoot.cs:
[XmlRoot(ElementName = "root", IsNullable = false)]
public class XmlRoot
{
[XmlElement(ElementName = "staff")]
public List<XmlRootStaff> Staff { get; set; } = new List<XmlRootStaff>();
}
XmlRootStaff.cs:
public class XmlRootStaff
{
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
[XmlElement(ElementName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "phone")]
public List<string> Phone { get; set; } = new List<string>();
}
To deserialize the XML (read from file) we'll use the following method:
DeserializeXMLFileToObject:
public static T DeserializeXMLFileToObject<T>(string xmlFilename)
{
T rObject = default(T);
try
{
if (string.IsNullOrEmpty(xmlFilename))
{
return default(T);
}
using (System.IO.StreamReader xmlStream = new System.IO.StreamReader(xmlFilename))
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
rObject = (T)serializer.Deserialize(xmlStream);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Error (DeserializeXMLFileToObject) - {ex.Message}");
throw;
}
return rObject;
}
Usage (deserialize):
private XmlRoot _root = null;
...
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "XML File (*.xml)|*.xml";
ofd.FileName = "Test.xml";
if (ofd.ShowDialog() == DialogResult.OK)
{
//deserialize
_root = HelperXml.DeserializeXMLFileToObject<XmlRoot>(ofd.FileName);
}
}
To serialize the XML (write to file) we'll use the following method:
SerializeObjectToXMLFile:
public static void SerializeObjectToXMLFile(object obj, string xmlFilename)
{
try
{
if (string.IsNullOrEmpty(xmlFilename))
{
return;
}//if
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
settings.OmitXmlDeclaration = false;
settings.Indent = true;
settings.NewLineHandling = System.Xml.NewLineHandling.Entitize;
using (System.Xml.XmlWriter xmlWriter = System.Xml.XmlWriter.Create(xmlFilename, settings))
{
//specify namespaces
System.Xml.Serialization.XmlSerializerNamespaces ns = new System.Xml.Serialization.XmlSerializerNamespaces();
ns.Add(string.Empty, "urn:none");
//create new instance
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
//write XML to file
serializer.Serialize(xmlWriter, obj, ns);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Error (SerializeObjectToXMLFile) - {ex.Message}");
throw;
}
}
Usage (serialize):
private XmlRoot _root = null;
...
using (SaveFileDialog sfd = new SaveFileDialog())
{
sfd.Filter = "XML File (*.xml)|*.xml";
sfd.FileName = "Test.xml";
if (sfd.ShowDialog() == DialogResult.OK)
{
//create new instance
_root = new XmlRoot();
//add data
_root.Staff.Add(new XmlRootStaff() { Id = "1", Name = "Name 1", Phone = new List<string>() { "123456" } });
_root.Staff.Add(new XmlRootStaff() { Id = "2", Name = "Name 2", Phone = new List<string>() { "123457", "123458" } });
//serialize - save to file
SerializeObjectToXMLFile(_root, sfd.FileName);
Debug.WriteLine($"Info: Saved to {sfd.FileName}");
}
}
To remove phone number 123458 where staff id = 2:
private void RemovePhone(string id, string phoneNumber)
{
if (_root != null)
{
for (int i = 0; i < _root.Staff.Count; i++)
{
if (_root.Staff[i].Id == id)
{
//remove
_root.Staff[i].Phone.Remove(phoneNumber);
break;
}
}
}
}
Resources:
LINQ to XML overview
XElement.Save Method
How to delete specific nodes from an XElement?
XML serialization
Examples of XML Serialization
Finally I solved changing:
program.cs
public static XmlDocument doc = new XmlDocument(); // ADDED THIS HERE
public static XmlNode staff;
public static XmlNodeList xnList = GetList();
public static XmlNodeList GetList()
{
XmlNodeList xnList;
// REMOVED XmlDocument from HERE
doc.Load(path);
xnList = doc.SelectNodes("/root/staff");
return xnList;
}
public static void GetID(string id)
{
foreach (XmlNode xn in xnList)
{
if(xn.Attributes["id"].Value == id)
{
staff = xn;
}
}
}
form1.cs
private void btnOK_Click(object sender, EventArgs e)
{
Program.staff["name"].InnerText = textBoxName.Text;
Program.staff["phone"].InnerText = textBoxPhone.Text;
if (Program.staff.SelectSingleNode("phone2") == null)
{
XmlElement elem = Program.doc.CreateElement("phone2");
elem.InnerText = textBoxPhone2.Text;
Program.staff.AppendChild(elem);
}
}

Deserialize returns null key and null value (count is correct)

I am experimenting with C# serialization, and had to serialize a Dictionary, as it isn't serializable I used an XML string, which then gets deserialized (example taken from https://blogs.msdn.microsoft.com/adam/2010/09/10/how-to-serialize-a-dictionary-or-hashtable-in-c/)
DictionaryDataItem class:
[Serializable]
public class DictionaryDataItem
{
public string Key;
public string Value;
public DictionaryDataItem(string key, string value)
{
Key = key;
Value = value;
}
public DictionaryDataItem()
{
Key = "";
Value = "";
}
}
Serialization code:
[WebMethod]
public string ListarPaises()
{
List<DictionaryDataItem> Paises = new List<DictionaryDataItem>();
XmlSerializer serializer = new XmlSerializer(typeof(List<DictionaryDataItem>));
StringWriter sw = new StringWriter();
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
try
{
Dictionary<string, string> diccionario = FabricaLogica.getLogicaGeneral().ListarPaises();
foreach (string key in diccionario.Keys)
{
Paises.Add(new DictionaryDataItem(key, diccionario[key]));
}
serializer.Serialize(sw, Paises, ns);
} catch (Exception ex)
{
ThrowSoapException(ex);
}
return sw.ToString();
}
The serialization works and it returns the following string as xml:
<string xmlns="http://tempuri.org/">
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfDictionaryDataItem>
<DictionaryDataItem>
<Key>ARG</Key>
<Value>ARGENTINA</Value>
</DictionaryDataItem>
<DictionaryDataItem>
<Key>BRA</Key>
<Value>BRASIL</Value>
</DictionaryDataItem>
<DictionaryDataItem>
<Key>URU</Key>
<Value>URUGUAY</Value>
</DictionaryDataItem>
</ArrayOfDictionaryDataItem>
</string>
And then, my deserialization code:
Dictionary<string, string> Paises = new Dictionary<string, string>();
string RawData = new WebService.WebService().ListarPaises();
XmlSerializer xs = new XmlSerializer(typeof(List<DictionaryDataItem>));
StringReader sr = new StringReader(RawData);
List<DictionaryDataItem> templist = (List<DictionaryDataItem>)xs.Deserialize(sr);
foreach (DictionaryDataItem di in templist)
{
Paises.Add(di.Key, di.Value);
}
return Paises;
I can see that templist has 3 items, but both key and value for all of the items is null.
Am I missing something?

XML-Serialization - How to pass an property-array without it loosing its XML-Attributes

I have two classes. One of the classes is containing an array of the other class.
I dont want the first Class to be serialized, only the array of the other class, so I am passing the array to the Serialization-Method, but it seems to be loosing its name, as it is later called ArrayOfSecondClass. Can someone help me with this?
Here is some Test-Code describing the Scenario:
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace TeaTimeTestEmpty
{
public class FirstClass
{
[XmlArray("RealName")] // Is ignored when SecondClassArray is passed
public SecondClass[] SecondClassArray { get; set; }
}
public class SecondClass
{
public string Name { get; set; }
}
public static class Program
{
public static string SerializeToXml(object objectToSerialize, Type objectType = null)
{
if (objectToSerialize != null)
{
if (objectType == null)
{
objectType = objectToSerialize.GetType();
}
XmlSerializer serializer = new XmlSerializer(objectType);
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, objectToSerialize, null);
string xmlString = "";
foreach (byte currentByte in stream.ToArray())
{
xmlString += (char)currentByte;
}
return xmlString;
}
}
return null;
}
static void Main(string[] args)
{
List<SecondClass> listOfSecondClasses = new List<SecondClass>();
for (int i = 0; i < 10; ++i)
{
listOfSecondClasses.Add(new SecondClass() { Name = "Bob" + i });
}
FirstClass firstClass = new FirstClass() { SecondClassArray = listOfSecondClasses.ToArray()};
// Note that I am passing only the SecondClassArray, not the whole Element
string xml = SerializeToXml(firstClass.SecondClassArray);
}
}
}
Now when I am debugging this, I get the following XML-Code in the variable xml:
<?xml version="1.0"?>
<ArrayOfSecondClass
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SecondClass>
<Name>Bob0</Name>
</SecondClass>
<SecondClass>
<Name>Bob1</Name>
</SecondClass>
<SecondClass>
<Name>Bob2</Name>
</SecondClass>
<SecondClass>
<Name>Bob3</Name>
</SecondClass>
<SecondClass>
<Name>Bob4</Name>
</SecondClass>
<SecondClass>
<Name>Bob5</Name>
</SecondClass>
<SecondClass>
<Name>Bob6</Name>
</SecondClass>
<SecondClass>
<Name>Bob7</Name>
</SecondClass>
<SecondClass>
<Name>Bob8</Name>
</SecondClass>
<SecondClass>
<Name>Bob9</Name>
</SecondClass>
</ArrayOfSecondClass>
My problem now is, that the Name I gave it in FirstClass is lost, and I cant seem to find a way to get it back, not even if I am giving the SecondClass XmlRoot or other tags, it is always calling it ArrayOfSecondClass instead of the wanted name.
I would appreciate it if you could give me a solution to how to give it the name I want it to have.
static void Main(string[] args)
{
List<SecondClass> listOfSecondClasses = new List<SecondClass>();
for (int i = 0; i < 10; ++i)
{
listOfSecondClasses.Add(new SecondClass() { Name = "Bob" + i });
}
FirstClass firstClass = new FirstClass() { SecondClassArray = listOfSecondClasses.ToArray() };
// Note that I am passing only the SecondClassArray, not the whole Element
string xml = SerializeToXml(firstClass.SecondClassArray,"RealNames");
Console.WriteLine(xml);
Console.ReadLine();
}
public static string SerializeToXml<T>(T objectToSerialize, string RootNodeName)
{
if (objectToSerialize != null)
{
XmlRootAttribute root = new XmlRootAttribute(RootNodeName);
XmlSerializer serializer = new XmlSerializer(typeof(T),root);
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, objectToSerialize, null);
string xmlString = "";
foreach (byte currentByte in stream.ToArray())
{
xmlString += (char)currentByte;
}
return xmlString;
}
}
return null;
}
The XmlArray attribute is part of FirstClass not of its property, so it is clear that it is not used when the serializer never sees an instance of FirstClass.
You will need to work with another constructor of the XmlSerializer class.
This constructor allows you to pass the name of the root element:
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "RealName";
XmlSerializer serializer = new XmlSerializer(objectType, xRoot);

XML Serialize Example, first steps

I have following exercise to do ...
I shall get following xml-file ...
<?xml version="1.0" encoding="UTF-8"?>
<Mitarbeiterstatistik xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Mitarbeiter>
<Vorname>Horst</Vorname>
<Nachname>Schneider</Nachname>
<Id>1</Id>
</Mitarbeiter>
<Mitarbeiter>
<Vorname>Tanja</Vorname>
<Nachname>Lindner</Nachname>
<Id>2</Id>
</Mitarbeiter>
</Mitarbeiterstatistik>
Now I tried following steps ...
I made a class Mitarbeiter!
public class Mitarbeiter
{
private string vorname;
private string nachname;
private int id;
public Mitarbeiter()
{
}
public Mitarbeiter(string vorname, string nachname, int id)
{
this.vorname = vorname;
this.nachname = nachname;
this.id = id;
}
public string Vorname
{
get { return vorname; }
set { vorname = value; }
}
public string Nachname
{
get { return nachname; }
set { nachname = value; }
}
public int Id
{
get { return id; }
set { id = value; }
}
}
Then I made a class Mitarbeiterstatistik with a list for Mitarbeiter objects ...
[XmlRoot("Mitarbeiterstatistik")]
public class Mitarbeiterstatistik
{
private List<Mitarbeiter> list = new List<Mitarbeiter>();
[XmlArray("List")]
public List<Mitarbeiter> List
{
get { return list; }
set { list = value; }
}
}
My Main-Class looks like ...
class Program
{
static void Main(string[] args)
{
Mitarbeiterstatistik maStatistik = new Mitarbeiterstatistik();
Mitarbeiter ma1 = new Mitarbeiter("Horst", "Schneider", 1);
Mitarbeiter ma2 = new Mitarbeiter("Tanja", "Lindner", 2);
maStatistik.List.Add(ma1);
maStatistik.List.Add(ma2);
XmlSerializer serializer = new XmlSerializer(typeof(Mitarbeiterstatistik));
XmlWriter writer = XmlWriter.Create(#"D:\test.xml");
serializer.Serialize(writer, maStatistik);
writer.Close();
}
}
Now I got following result ...
<?xml version="1.0" encoding="UTF-8"?>
<Mitarbeiterstatistik xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
**<List>**
<Mitarbeiter>
<Vorname>Horst</Vorname>
<Nachname>Schneider</Nachname>
<Id>1</Id>
</Mitarbeiter>
<Mitarbeiter>
<Vorname>Tanja</Vorname>
<Nachname>Schneider</Nachname>
<Id>2</Id>
</Mitarbeiter>
**</List>**
</Mitarbeiterstatistik>
No I have an Element "List" in my Xml-file ... :-)
What can I do against my problem ...
Is there only the possibility to define only a Mitarbeiter class and NO Mitarbeiterstatistik-Class?
Maybe as following?
List<Mitarbeiter> list = new List<Mitarbeiter>();
Mitarbeiter ma1 = new Mitarbeiter("Horst", "Schneider", 1);
Mitarbeiter ma2 = new Mitarbeiter("Tanja", "Lindner", 2);
list.Add(ma1);
list.Add(ma2);
XmlSerializer serializer = new XmlSerializer(typeof(List<Mitarbeiter>), new XmlRootAttribute("Mitarbeiterstatistik"));
XmlWriter writer = XmlWriter.Create(#"D:\test.xml");
serializer.Serialize(writer, list);
writer.Close();
Or is there a chance to keep my Mitarbeiterstatistik-Class??? And disable my List-Element???
If you want to try Linq To Xml:
XDocument xDoc = new XDocument(new XElement("Mitarbeiterstatistik"));
foreach (var mitarbeiter in list)
{
xDoc.Root.Add(
new XElement("Mitarbeiter",
new XElement("Vorname" ,mitarbeiter.Vorname ),
new XElement("Nachname" ,mitarbeiter.Nachname ),
new XElement("Id" ,mitarbeiter.Id )));
}
xDoc.Save(#"d:\test.xml");
You can get out of attribute "List" (as i undestand your question correctly) using [XmlElement] with name of element you want to get instead of [XmlArray]:
[XmlRoot("Mitarbeiterstatistik")]
public class Mitarbeiterstatistik
{
private List<Mitarbeiter> list = new List<Mitarbeiter>();
[XmlElement("Mitarbeiter")]
public List<Mitarbeiter> List {get; set;}
}

not able to Deserialize xml into object

I am having following peice of code ,where in i am trying to serialize and deserailize object of StringResource class.
Please note Resource1.stringXml = its coming from resource file.If i pass strelemet.outerXMl i get the object from Deserialize object ,but if i pass Resource1.stringXml i am getting following exception
{"< STRING xmlns=''> was not expected."} System.Exception {System.InvalidOperationException}
class Program
{
static void Main(string[] args)
{
StringResource str = new StringResource();
str.DELETE = "CanDelete";
str.ID= "23342";
XmlElement strelemet = SerializeObjectToXmlNode (str);
StringResource strResourceObject = DeSerializeXmlNodeToObject<StringResource>(Resource1.stringXml);
Console.ReadLine();
}
public static T DeSerializeXmlNodeToObject<T>(string objectNodeOuterXml)
{
try
{
TextReader objStringsTextReader = new StringReader(objectNodeOuterXml);
XmlSerializer stringResourceSerializer = new XmlSerializer(typeof(T),string.Empty);
return (T)stringResourceSerializer.Deserialize(objStringsTextReader);
}
catch (Exception excep)
{
return default(T);
}
}
public static XmlElement SerializeObjectToXmlNode(object obj)
{
using (MemoryStream memoryStream = new MemoryStream())
{
try
{
XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add(string.Empty, string.Empty);
XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.CloseOutput = false;
writerSettings.Encoding = System.Text.Encoding.UTF8;
writerSettings.Indent = false;
writerSettings.OmitXmlDeclaration = true;
XmlWriter writer = XmlWriter.Create(memoryStream, writerSettings);
XmlSerializer xmlserializer = new XmlSerializer(obj.GetType());
xmlserializer.Serialize(writer, obj, xmlNameSpace);
writer.Close();
memoryStream.Position = 0;
XmlDocument serializeObjectDoc = new XmlDocument();
serializeObjectDoc.Load(memoryStream);
return serializeObjectDoc.DocumentElement;
}
catch (Exception excep)
{
return null;
}
}
}
}
public class StringResource
{
[XmlAttribute]
public string DELETE;
[XmlAttribute]
public string ID;
}
< STRING ID="1" DELETE="True" />
Problem is a name mismatch in your XML root node and your class
< STRING ID="1" DELETE="True" /> -- STRING here
public class StringResource -- StringResource Here.
Add xmlroot attribute to your class, and will see what happens
[XmlRoot( "STRING " )]
public class StringResource
{
[XmlAttribute]
public string DELETE;
[XmlAttribute]
public string ID;
}
Wel it's obvious Resource1.stringXml does not contain a correct XML which could be deserialized to a StringResource object. The XML should look like this:
<StringResource DELETE="CanDelete" ID="23342" />

Categories

Resources