I have a class representing a book and when I run the SerializeToXmlElement()
method, it includes the class but not the class properties. How can I ensure that the public properties are included in the XML output?
Book class
[XmlType("Edition")]
public class Book
{
#region Attributes
private string series;
private string title;
private string isbn;
private string pubDate;
#endregion Attributes
#region Encapsulated fields
[XmlElement]
public string Series { get => series; set => series = value; }
[XmlElement]
public string Title { get => title; set => title = value; }
[XmlElement("ISBN")]
public string Isbn { get => isbn; set => isbn = value; }
[XmlElement("Publication_Date")]
public string EditionPubDate { get => pubDate; set => pubDate = value; }
#endregion Encapsulated fields
#region Constructors
public Book() { }
#endregion Constructors
#region Methods
public XmlElement SerializeToXmlElement()
{
XmlDocument doc = new XmlDocument();
using (XmlWriter writer = doc.CreateNavigator().AppendChild())
{
new XmlSerializer(this.GetType()).Serialize(writer, this);
}
return doc.DocumentElement;
}
#endregion Methods
}
Input
XmlDocument doc = new XmlDocument();
doc.AppendChild(doc.CreateXmlDeclaration("1.0","utf-8",null));
XmlNode rootnode = doc.AppendChild(doc.CreateElement("Root_Node"));
XmlNode editionsNode = rootnode.AppendChild(doc.CreateElement("Editions"));
Book b = new Book();
b.Isbn = "978-0-553-10953-5";
b.Title = "A Brief History of Time";
XmlNode edition = doc.ImportNode(b.SerializeToXmlElement(), false);
editionsNode.AppendChild(edition);
edition.AppendChild(doc.CreateElement("Impressions"));
Output
<Root_Node>
<Editions>
<Edition xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Impressions />
</Edition>
</Editions>
</Root_Node>
Bonus points for someone who can tell me how I can remove the xmlns:xsi
and xmlns:xsd
attributes from the Edition node in the XML output.
You need to pass true
for the second parameter to XmlDocument.ImportNode(XmlNode, Boolean)
:
deep
Type: System.Boolean
true to perform a deep clone; otherwise, false.
This indicates that the child nodes of the incoming node should be copied as well. Thus, your code should look like:
XmlNode edition = doc.ImportNode(b.SerializeToXmlElement(), true);
Bonus points for someone who can tell me how I can remove the xmlns:xsi
and xmlns:xsd
attributes from the Edition node in the XML output.
As explained in this answer to Omitting all xsi and xsd namespaces when serializing an object in .NET? by Thomas Levesque you need to pass an XmlSerializerNamespaces
with an empty name/namespace pair into Serialize()
:
public XmlElement SerializeToXmlElement()
{
XmlDocument doc = new XmlDocument();
using (XmlWriter writer = doc.CreateNavigator().AppendChild())
{
var ns = new XmlSerializerNamespaces();
ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
new XmlSerializer(this.GetType()).Serialize(writer, this, ns);
}
return doc.DocumentElement;
}
Working .Net fiddle.