Search code examples
c#xml-serializationxmlserializerxmlwriter

How to set XmlWriter.XmlWriterSettings when created from XPathNavigator.AppendChild()?


I need to set the OmitXmlDeclaration property of the XmlWriterSettings for a XmlWriter to false to not have XML declarations created. The issue is that I have created the XmlWriter from a call of a XPathNavigator.AppendChild() method. Code below:

    public String GetEntityXml<T>(List<T> entities)
    {
        XmlDocument xmlDoc = new XmlDocument();
        XPathNavigator nav = xmlDoc.CreateNavigator();

        using (XmlWriter writer = nav.AppendChild())
        {

            XmlSerializer ser = new XmlSerializer(typeof(List<T>), new XmlRootAttribute(typeof(T).Name + "_LIST"));
            ser.Serialize(writer, entities);
        }

        StringWriter stringWriter = new StringWriter();
        XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);

        xmlDoc.WriteTo(xmlTextWriter);

        string resultString = stringWriter.ToString();

        stringWriter.Close();
        xmlTextWriter.Close();

        return resultString;
    }

Any idea how to serialize the List and not have XML declarations?


Solution

  • I’m not getting the XML declaration when I execute your code. Serializing a List<int> gives me:

    <Int32_LIST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <int>5</int>
      <int>7</int>
      <int>2</int>
    </Int32_LIST>
    

    Note that the “XML declaration” that OmitXmlDeclaration refers to is typically something similar to:

    <?xml version="1.0" encoding="UTF-8" ?>
    

    If you’re instead referring to the xmlns parts, then those are called “XML namespace declarations”, and may be eliminated by initializing an XmlSerializerNamespaces instance with a default empty namespace, and passing it to your Serialize method:

    XmlSerializer ser = new XmlSerializer(typeof(List<T>), new XmlRootAttribute(typeof(T).Name + "_LIST"));
    var namespaces = new XmlSerializerNamespaces(new[] { new XmlQualifiedName("", "") });
    ser.Serialize(writer, entities, namespaces);
    

    The below is a shortened implementation which achieves the same result as your code:

    public String GetEntityXml<T>(List<T> entities)
    {
        var sb = new StringBuilder();
        var settings = new XmlWriterSettings { OmitXmlDeclaration = true };
        using (XmlWriter writer = XmlWriter.Create(sb, settings))
        {
            XmlSerializer ser = new XmlSerializer(typeof(List<T>), new XmlRootAttribute(typeof(T).Name + "_LIST"));
            var namespaces = new XmlSerializerNamespaces(new[] { new XmlQualifiedName("", "") });
            ser.Serialize(writer, entities, namespaces);
        }
        return sb.ToString();
    }