2011-02-18 1099 views
39

我从Web服务获取XML。这里是XML的样子:XML错误:有多个根元素

<parent> 
    <child> 
     Text 
    </child> 
</parent> 
<parent> 
    <child> 
     <grandchild> 
      Text 
     </grandchild> 
     <grandchild> 
      Text 
     </grandchild> 
    </child> 
    <child> 
     Text 
    </child> 
</parent> 

etc. 

这里是我的C#代码:

StringBuilder output = new StringBuilder(); 

// Create an XmlReader 
using (XmlReader reader = XmlReader.Create(new StringReader([email protected]))) 
{ 
    XmlWriterSettings ws = new XmlWriterSettings(); 
    //ws.Indent = true; 
    using (XmlWriter writer = XmlWriter.Create(output, ws)) 
    { 
     // Parse the file and display each of the nodes. 
     while (reader.Read()) 
     { 
      switch (reader.NodeType) 
      { 
       case XmlNodeType.Element: 
        writer.WriteStartElement(reader.Name); 
        break; 
       case XmlNodeType.Text: 
        writer.WriteString(reader.Value); 
        break; 
       case XmlNodeType.XmlDeclaration: 
       case XmlNodeType.ProcessingInstruction: 
        writer.WriteProcessingInstruction(reader.Name, reader.Value); 
        break; 
       case XmlNodeType.Comment: 
        writer.WriteComment(reader.Value); 
        break; 
       case XmlNodeType.EndElement: 
        writer.WriteFullEndElement(); 
        break; 
      } 
     } 
    } 
} 

我认为错误是第二父元素抛出。我怎样才能避免这个错误?任何帮助是极大的赞赏。

+4

嗯,首先,你从Web服务获得的东西*不是* XML,因为它有两个根元素,这是什么导致你的问题。你如何从Web服务中获得它?你是否在某种程度上不小心修剪了真正的根部元素? – 2011-02-18 15:10:41

+0

@Matt - 不,我从Web服务逐字返回响应。 – divided 2011-02-18 15:20:21

回答

49

您需要括在周围的元素你<parent>元素作为XML文档只能有一个根节点:

<parents> <!-- I've added this tag --> 
    <parent> 
     <child> 
      Text 
     </child> 
    </parent> 
    <parent> 
     <child> 
      <grandchild> 
       Text 
      </grandchild> 
      <grandchild> 
       Text 
      </grandchild> 
     </child> 
     <child> 
      Text 
     </child> 
    </parent> 
<parents> <!-- I've added this tag --> 

正如你从别的地方接收到这个标记,而不是生成它自己,你可能不得不通过将响应视为字符串并用适当的标签包装它,然后尝试将其解析为XML。

所以,你已经有几条路:

  1. 获取网络服务的提供者返回你实际 XML有一个根节点
  2. 预先处理XML,因为我“VE上面所建议的,要添加根节点
  3. 预处理的XML将其分割成多个块(即,一个用于每个<parent>节点)和过程中的每个作为不同的XML文档
9

裹在另一个元素的XML

<wrapper> 
<parent> 
    <child> 
     Text 
    </child> 
</parent> 
<parent> 
    <child> 
     <grandchild> 
      Text 
     </grandchild> 
     <grandchild> 
      Text 
     </grandchild> 
    </child> 
    <child> 
     Text 
    </child> 
</parent> 
</wrapper> 
6

如果你负责(或通过网络进行服务的任何控制),让他们增添独一无二的根元素!

如果你根本不能改变它,那么你可以做一些正则表达式或字符串分割来解析每一个元素,并将每个元素传递给你的XML Reader。

或者,您可以手动添加垃圾根元素,方法是在开始标记前添加一个结束标记并加后缀。

63

您可以在不修改XML流的情况下执行此操作:告诉XmlReader不要太挑剔。 将XmlReaderSettings.ConformanceLevel设置为ConformanceLevel.Fragment将使解析器忽略没有根节点的事实。

 XmlReaderSettings settings = new XmlReaderSettings(); 
     settings.ConformanceLevel = ConformanceLevel.Fragment; 
     using (XmlReader reader = XmlReader.Create(tr,settings)) 
     { 
      ... 
     } 

现在,您可以解析类似这样的内容(这是一个实时XML流,无法用节点包装)。

<event> 
    <timeStamp>1354902435238</timeStamp> 
    <eventId>7073822</eventId> 
</event> 
<data> 
    <time>1354902435341</time> 
    <payload type='80'>7d1300786a0000000bf9458b0518000000000000000000000000000000000c0c030306001b</payload> 
</data> 
<data> 
    <time>1354902435345</time> 
    <payload type='80'>fd1260780912ff3028fea5ffc0387d640fa550f40fbdf7afffe001fff8200fff00f0bf0e000042201421100224ff40312300111400004f000000e0c0fbd1e0000f10e0fccc2ff0000f0fe00f00f0eed00f11e10d010021420401</payload> 
</data> 
<data> 
    <time>1354902435347</time> 
    <payload type='80'>fd126078ad11fc4015fefdf5b042ff1010223500000000000000003007ff00f20e0f01000e0000dc0f01000f000000000000004f000000f104ff001000210f000013010000c6da000000680ffa807800200000000d00c0f0</payload> 
</data>