views:

451

answers:

1

I am building an XmlDocument on the fly in .NET with an xml document. I then transform that with the Transform() method of an XslCompiledTransform.

The Transform() method threw an exception because an invalid character for the encoding was found in the stream. When I copy/paste the string with the help of the TextVisualizer in Visual Studio into Altova XmlSpy, it does not find an encoding problem.

I tried adding a UTF-16 header to the document to make it render as UTF-16 and calling Transform from the resulting text led to it complain about a BOM. Below is a simplified version of the code I used.

            XmlDocument document = new XmlDocument();
            XmlDeclaration decl = document.CreateXmlDeclaration("1.0", "UTF-16", null);
            document.AppendChild(decl);

            XmlNode root = document.CreateNode(XmlNodeType.Element, "RootNode", "");
            XmlNode nodeOne = document.CreateNode(XmlNodeType.Element, "FirstChild", null);
            XmlNode nodeTwp = doc.CreateNode(XmlNodeType.Element, "Second Child", null);

            root.AppendChild(nodeOne);
            root.AppendChild(nodeTwo);
            document.AppendChild(root);

Which I consequently am writing to a string like so:

        StringBuilder sbXml = new StringBuilder();
        using (XmlWriter wtr = XmlWriter.Create(sbXml))
        {
            xml.WriteTo(wtr);
            // More code that calls sbXml.ToString());
        }

What must I do to add the BOM or get XslCompiledTransform.Transform to not care about the bom?

+2  A: 

You don't need to manually add the xml declaration.

This code will add the BOM and the declaration to the output.

XmlDocument document = new XmlDocument(); 
// XmlDeclaration decl = document.CreateXmlDeclaration("1.0", "UTF-16", null); 
// document.AppendChild(decl); 
XmlNode root = document.CreateNode(XmlNodeType.Element, "RootNode", ""); 
XmlNode nodeOne = document.CreateNode(XmlNodeType.Element, "FirstChild", null);
XmlNode nodeTwo = document.CreateNode(XmlNodeType.Element, "SecondChild", null); 
root.AppendChild(nodeOne); 
root.AppendChild(nodeTwo); 
document.AppendChild(root);

using(MemoryStream ms = new MemoryStream())
{
    StreamWriter sw = new StreamWriter(ms, Encoding.Unicode);
    document.Save(sw);
    Console.Write(System.Text.Encoding.Unicode.GetString(ms.ToArray()));
}

If you need the output as a byte[], you can use the output from ms.ToArray(). Otherwise you can use the appropriate System.Text.Encoding encoding to translate the byte[] into a variety of encodings.

Michael McCloskey