XDocument to string: How to omit encoding in decla

2019-06-21 20:02发布

问题:

I'm writing a wrapper for a braindead enterprise XML API. I have an XDocument that I need to turn into a string. Due to the fact that their XML parser is so finicky that it cannot even handle whitespace between XML nodes, the document declaration MUST be EXACTLY:

<?xml version="1.0"?>

However, the XDocument.Save() method always adds an encoding attribute in that declaration:

<?xml version="1.0" encoding="utf-16"?>

With the past hour spent on Google and Stack looking for the best way to generate the XML string, the best I can do is:

string result = xmlStringBuilder.ToString().Replace(@"encoding=""utf-16"", string.Empty));

I've tried

xdoc.Declaration = new XDeclaration("1.0", null, null);

and that does succeed at setting the declaration in the XDocument the way I want it; however, when I call the Save() method, the encoding attribute gets magically thrown back in there, no matter what route I go (using TextWriter, adding XmlWriterSettings, etc.).

Does anyone have a better way to do this, or is my code forever doomed to have a paragraph of ranting in comments above the hideous string replace?

回答1:

Well the receiving end should be fixed to use an XML parser and not something that breaks with XML syntax but with .NET if you want to create a string with the XML declaration as you posted it the following approach works for me:

public class MyStringWriter : StringWriter
{
    public override Encoding Encoding
    {
        get
        {
            return null;
        }
    }
}

and then

    XDocument doc = new XDocument(
        new XDeclaration("1.0", null, null),
        new XElement("root", "test")
        );

    string xml;

    using (StringWriter msw = new MyStringWriter())
    {
        doc.Save(msw);
        xml = msw.ToString();
    }

    Console.WriteLine(xml);

outputs

<?xml version="1.0"?>
<root>test</root>