如何使用.NET控制xml序列化的<?xml?>部分?

Chr*_*ris 13 .net xml-serialization

我正在使用此方法序列化我的对象:

public static string XmlSerialize(object o)
{
    var stringWriter = new StringWriter();
    var xmlSerializer = new XmlSerializer(o.GetType());
    xmlSerializer.Serialize(stringWriter, o);
    string xml = stringWriter.ToString();
    stringWriter.Close();
    return xml;
}
Run Code Online (Sandbox Code Playgroud)

它使XML像这样开始:

<?xml version="1.0" encoding="utf-16"?>
<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
Run Code Online (Sandbox Code Playgroud)

但我希望它看起来像这样:

<?xml version = "1.0" encoding="Windows-1252" standalone="yes"?>
<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
Run Code Online (Sandbox Code Playgroud)

那么,如何将编码更改为Windows-1252并设置standalone = yes?另外,如何让对象排除xmlns值?

我见过几个类似的问题,比如这个问题,但是我希望它对我来说可能更简单,也许是通过在某个地方设置一些属性?

更新2:在查看John的回答和评论之后,再考虑这个问题,我决定采用第二种方法.我不认为一次为第三方创建这个古怪的自定义xml应该被称为通用的"XmlSerialize".

所以,我创建了第二个获取XML文档的方法,首先,删除一个名称空间元素,如下所示:

xElement.Attributes().Where(a => a.IsNamespaceDeclaration && a.Value == "http://www.w3.org/2001/XMLSchema").Remove();
Run Code Online (Sandbox Code Playgroud)

然后,它用John的代码将它写入XML.最后它返回xml,遵循以下输出:

new XDeclaration("1.0", "Windows-1252", "yes").ToString()
Run Code Online (Sandbox Code Playgroud)

这很难看,但它让我真正得到了第三方理解我的XML所需要的东西.

Joh*_*ers 25

试试这个:

public static string XmlSerialize(object o)
{
    using (var stringWriter = new StringWriter())
    {
        var settings = new XmlWriterSettings
                           {
                               Encoding = Encoding.GetEncoding(1252),
                               OmitXmlDeclaration = true
                           };
        using (var writer = XmlWriter.Create(stringWriter, settings))
        {
            var xmlSerializer = new XmlSerializer(o.GetType());
            xmlSerializer.Serialize(writer, o);
        }
        return stringWriter.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

这不会摆脱xsd:名称空间,但那么,你为什么要这样做?


更新:似乎无论何时使用a StringWriter,你都会获得UTF-16,即使你XmlWriter在编码集上使用它也是如此.下一步是写出来MemoryStream.但这引发了为什么要返回一个字符串的问题.例如,如果您要转向并将字符串输出到流,那么我们应该直接输出到此流.同样的TextWriter.

  • 在大多数情况下,我使用`var`的原因是可以自由更改返回的类型而无需更改声明. (6认同)
  • 摆脱OmitXmlDeclaration = true,你应该有声明.如果他们扼杀xsd声明,你需要非常努力地踢你的API人员**.如果需要指定xsi:type,则必须使用.如果我们不都遵循标准,很快XML就不会成为标准. (2认同)