2012-02-10 45 views
3

我需要将XmlWriter的XmlWriterSettings的OmitXmlDeclaration属性设置为false,以便不创建XML声明。问题是我从XPathNavigator.AppendChild()方法的调用中创建了XmlWriter。代码如下:如何从XPathNavigator.AppendChild()创建时设置XmlWriter.XmlWriterSettings?

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; 
    } 

任何想法如何序列化列表,并没有XML声明?

+0

在我的回答,我假设你正在试图序列化的XML添加到现有的文档。是这样吗?另外,你是否需要从resultString中省略xml声明? – rsbarro 2012-02-11 14:55:45

+0

rsbarro - 你是对的。我正在寻找获取实体集合的xml序列化,然后将其添加到具有多个序列化的组合文档中。 – 2012-02-12 14:33:52

回答

3

我在执行代码时没有获取XML声明。序列化List<int>给我:

<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> 

注意“XML声明”是OmitXmlDeclaration是指通常类似于:

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

如果你不是指xmlns部分,那么这些被称为“XML 名称空间声明”,并且可以通过使用默认空名称空间初始化XmlSerializerNamespaces实例并将其传递到Serialize方法来消除:

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); 

下面是一个缩短实现其达到相同的结果代码:

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(); 
} 
+0

我认为示例代码有点误导。我假设他试图将孩子添加到已经存在的XML文档中,在这种情况下,'XmlSerializer'确实写出了xml声明并导致其示例代码崩溃。取出示例代码并在声明xmlDoc后添加以下内容,您将看到我的意思:'xmlDoc.LoadXml(“”); var nav = xmlDoc.DocumentElement。CreateNavigator();' – rsbarro 2012-02-10 19:32:51

+0

是的,可能是这种情况。考虑到他已经知道他可以直接初始化'XmlWriter',所以'XPathNavigator'的创建看起来毫无意义。 – Douglas 2012-02-10 19:58:16

+0

按我的需要工作。谢谢!!! – 2012-02-12 18:57:23

2

试试这个办法(切换到var的可读性):

public String GetEntityXml<T>(List<T> entities) 
{ 
    var xmlDoc = new XmlDocument(); 
    var nav = xmlDoc.CreateNavigator(); 
    using (var sw = new StringWriter()) 
    { 
     //Create an XmlWriter that will omit xml declarations 
     var s = new XmlWriterSettings{ OmitXmlDeclaration = true }; 
     using (var xmlWriter = XmlWriter.Create(sw, s)) 
     { 
      //Use the following to serialize without namespaces 
      var ns = new XmlSerializerNamespaces(); 
      ns.Add("", ""); 
      var ser = new XmlSerializer(typeof(List<T>), 
          new XmlRootAttribute(typeof(T).Name + "_LIST")); 
      ser.Serialize(xmlWriter, entities, ns); 
     } 

     //Pass xml string to nav.AppendChild() 
     nav.AppendChild(sw.ToString()); 
    } 

    using (var stringWriter = new StringWriter()) 
    { 
     using (var xmlTextWriter = XmlWriter.Create(stringWriter)) 
     { 
      xmlDoc.WriteTo(xmlTextWriter); 
     } 
     return stringWriter.ToString(); 
    } 
} 

而不是使用nav.AppendChild()创建XmlWriter,您可以分别创建XmlWriter,然后只用nav.AppendChild(string)到XML写入xmlDoc。当您自己创建XmlWriter时,可以省略XML声明。另外,当你序列化时,你可能想要使用XmlSerializerNamespaces类来省略xmlns:xsixmlns:xsd命名空间。

+0

-1:请用'XmlWriter.Create()'替换'new XmlTextWriter()',我会upvote。 – 2012-02-11 02:08:33

+0

@JohnSaunders更新,但我只是从OP复制代码。我不认为这部分代码与他所问的问题有关。 =]我很确定他想知道如何将序列化的xml插入到现有的xml文档中(因为有其他答案明确指出,有更简单的方法来编写'GetEntityXml'方法)。 – rsbarro 2012-02-11 02:18:18

+0

+1读者复制并粘贴我们发布的代码,即使我们打算将其作为其他内容的示例。顺便说一下,因为我心情很好,所以我让你不用“使用”块。 – 2012-02-11 03:19:25