Reputation: 272
I have a class which I want to serialize to xml. I want to move one of the properties down a level in the generated xml (an element within an element) without changing the structure of the class. Is it possible to do this using XmlSerializer?
An example:
Generated xml:
<Person>
<firstname xmlns=\"http://myschema.com\">John</firstname>
<postcode xmlns=\"http://myschema.com\">N1 0XE</postcode>
</Person>
Desired xml:
<Person>
<firstname xmlns=\"http://myschema.com\">John</firstname>
<address>
<postcode xmlns=\"http://myschema.com\">N1 0XE</postcode>
</address>
</Person>
The code:
[Serializable]
[XmlType(Namespace = "http://myschema.com")]
public class Person
{
[XmlElement("firstname")]
public string FirstName { get; set; }
[XmlElement("postcode")]
public string Postcode { get; set; }
}
Serializer:
var xmlSerializer = new XmlSerializer(typeof(Person));
var stringWriter = new StringWriter();
var xmlWriter = XmlWriter.Create(stringWriter);
xmlSerializer.Serialize(xmlWriter, person);
Upvotes: 2
Views: 1913
Reputation: 20076
There are two other ways out which require no changes whatsoever (not even implementing IXmlSerializable) to your class:
<address>
in an element as it is written;Upvotes: 1
Reputation: 8359
The only way I know to change the generated standard output xml is to implement IXmlSerializable. So you do not have to change the common structure but you do have to provide the implementation for some methods.
public class Person : IXmlSerializable
{
[XmlElement("firstname")]
public string FirstName { get; set; }
[XmlElement("postcode")]
public string Postcode { get; set; }
#region IXmlSerializable Member
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
if (reader.Read())
{
FirstName = reader.ReadInnerXml();
}
reader.Read();
Postcode = reader.ReadInnerXml();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteElementString("firstname ", FirstName);
writer.WriteStartElement("address");
writer.WriteElementString("postcode", Postcode);
writer.WriteEndElement();
}
#endregion
// for demo purposes only !
public override string ToString()
{
return FirstName + ", " + Postcode;
}
// source to test the exported file and read it right after!
Person p = new Person() { FirstName = "jon doe", Postcode = "N1 OX" };
XmlSerializer xs = new XmlSerializer(typeof(Person));
StreamWriter sw = new StreamWriter("export.xml");
xs.Serialize(sw, p);
sw.Close();
StreamReader sr = new StreamReader("export.xml");
Person p1 = xs.Deserialize(sr) as Person;
Debug.WriteLine(p1.ToString());
@XmlSubElement - there are only a bunch of attributes available for xmlSerialization. Unfortunatelly there is no subElement or anything comparable.
Upvotes: 3