I have a sipmle class
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public ICollection<Address> AllAddress { get; set; }
}
public class Address
{
public string Street { get; set; }
}
If i serialize People instance uses default XmlSerializer then i will get
<Person xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Id>2</Id>
<Name>FIO FIO IFO</Name>
<Address>
<Street>Golden Gate</Street>
</Address>
</Person>
How do I get this result?
<struct n="People">
<attr n="id">2</attr >
<attr n="name">FIO FIO IFO</attr >
<struct n="Address">
<attr n="street">Golden Gate</attr>
</struct >
</struct>
It seems you have to convert your xml to custom format so you have to implement IXmlSerializable
interface in your Person
class object like.
public class Person : IXmlSerializable
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public XmlSchema GetSchema() { throw new NotImplementedException(); }
public void ReadXml(XmlReader reader)
{
while (reader.Read())
{
if (reader.Name == "attr" && reader.GetAttribute("n") == "id")
Id = Convert.ToInt32(reader.ReadInnerXml());
if (reader.Name == "attr" && reader.GetAttribute("n") == "name")
Name = reader.ReadInnerXml();
if (reader.Name == "attr" && reader.GetAttribute("n") == "street")
Address = new Address { Street = reader.ReadInnerXml() };
}
}
public void WriteXml(XmlWriter writer)
{
//Start "struct"
writer.WriteStartElement("struct");
writer.WriteAttributeString("n", "People");
writer.WriteStartElement("attr");
writer.WriteAttributeString("n", "id");
writer.WriteString(Id.ToString());
writer.WriteEndElement();
writer.WriteStartElement("attr");
writer.WriteAttributeString("n", "name");
writer.WriteString(Name.ToString());
writer.WriteEndElement();
//Start inner "struct"
writer.WriteStartElement("struct");
writer.WriteAttributeString("n", "Address");
writer.WriteStartElement("attr");
writer.WriteAttributeString("n", "street");
writer.WriteString(Address.Street.ToString());
writer.WriteEndElement();
//End inner "struct"
writer.WriteEndElement();
//End "struct"
writer.WriteEndElement();
}
}
And you can serialize and deserialize your xml like.
Person person = new Person
{
Id = 2,
Name = "FIO FIO IFO",
Address = new Address { Street = "Golden Gate" }
};
//--------------------Serialization----------------------------
XmlSerializer serializer = new XmlSerializer(person.GetType());
using (StreamWriter writer = new StreamWriter(@"Path to xml file"))
{
serializer.Serialize(writer, person);
}
//--------------------Deserialization----------------------------
using (StringReader stringReader = new StringReader(File.ReadAllText(@"Path to same xml file that generated by above serializer")))
{
person = (Person)serializer.Deserialize(stringReader);
Console.WriteLine("Id: " + person.Id);
Console.WriteLine("Name: " + person.Name);
Console.WriteLine("Street: " + person.Address.Street);
Console.ReadLine();
}
Output for Serialization:
Output for Deserialization:
You can also create a custom methods to read and write xml.
1) Write
public static void WriteXml(Person person, string path)
{
using (XmlWriter writer = XmlWriter.Create(path))
{
//Start "struct"
writer.WriteStartElement("struct");
writer.WriteAttributeString("n", "People");
writer.WriteStartElement("attr");
writer.WriteAttributeString("n", "id");
writer.WriteString(person.Id.ToString());
writer.WriteEndElement();
writer.WriteStartElement("attr");
writer.WriteAttributeString("n", "name");
writer.WriteString(person.Name.ToString());
writer.WriteEndElement();
//Start inner "struct"
writer.WriteStartElement("struct");
writer.WriteAttributeString("n", "Address");
writer.WriteStartElement("attr");
writer.WriteAttributeString("n", "street");
writer.WriteString(person.Address.Street.ToString());
writer.WriteEndElement();
//End inner "struct"
writer.WriteEndElement();
//End "struct"
writer.WriteEndElement();
}
}
Usage:
Person person = new Person
{
Id = 2,
Name = "FIO FIO IFO",
Address = new Address { Street = "Golden Gate" }
};
WriteXml(person, @"Path to xml file");
2) Read
public static Person ReadXml(string path)
{
Person person = new Person();
using (XmlReader reader = XmlReader.Create(path))
{
while (reader.Read())
{
if (reader.Name == "attr" && reader.GetAttribute("n") == "id")
person.Id = Convert.ToInt32(reader.ReadInnerXml());
if (reader.Name == "attr" && reader.GetAttribute("n") == "name")
person.Name = reader.ReadInnerXml();
if (reader.Name == "attr" && reader.GetAttribute("n") == "street")
person.Address = new Address { Street = reader.ReadInnerXml() };
}
}
return person;
}
Usage:
Person result = ReadXml(@"Path to same xml file that generated by above serializer");