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

时间:2009-09-15 21:00:51

标签: .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;
}

它使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">

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

<?xml version = "1.0" encoding="Windows-1252" standalone="yes"?>
<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

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

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

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

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

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

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

new XDeclaration("1.0", "Windows-1252", "yes").ToString()

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

3 个答案:

答案 0 :(得分: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();
    }
}

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


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

答案 1 :(得分:2)

您可以使用XmlTextWriter而不是StringWriter。以下是我的一些代码与您的编码集的摘录。

XmlTextWriter textWriter = new XmlTextWriter(stream, Encoding.GetEncoding(1252));
textWriter.Namespaces = false;

答案 2 :(得分:0)

FWIW,我通过使用带有XMLWriterSettings的XmlWriter来实现编码。这是一个示例:

...  
// My object type was from a class generated by xsd.  
XmlSerializer xms = new XmlSerializer(typeof(SomeType));  
SomeType objSt;
using(FileStream fs = new FileStream("C:\SomeFile.xml", FileMode.Open, FileAccess.Read))
{    
  using(XmlReader xr = XmlReader.Create(fs))  // Supposed to preserve encoding.  
  {  
    objSt = (SomeType)xms.Deserialize(xr);  
  }    
}  

...  
...  // Do some stuff, change some attribute values.  
...  

XmlWriterSettings xsw= new XmlWriterSettings();  
xsw.Indent= true;  
xsw.NewLineOnAttributes= true;  
xsw.Encoding = Encoding.GetEncoding(1252);  
using(XmlWriter xwXsw = XmlWriter.Create("C:\SomeFile_Changed.xml",xsw))
{    
  xms.Serialize(xwXsw, objSt);  
}  
...  
...  // Finish up and get out.
...  

出于某种原因,我只能使用XmlSerializer对象并使用TextWriter进行序列化,因为根据MS帮助XmlSerializer.Deserialize(XmlReader)“XmlReader自动检测并使用指定的编码通过XML文档。“然后我开始玩XmlWriterSettings并打破了一些东西......