如何为特定值解析多个元素

问题描述:

我正在从Web服务接收一串XML,并解析它以获取我需要保存的一些值。我将字符串放入XmlDocument中,并使用XmlNodeReader来解析元素名称并获取值。如何为特定值解析多个元素

这是天晴的时候我后的值命名,如在这个片段类型,ID或来源:

<WebResult> 
    <Header> 
     <Type>Success</Type> 
     <ID>52347</ID> 
    </Header> 
    <Source>Global</Source> 
    <ReturnItems> 
    <ReturnItem> 
     <DataName>SaleID</DataName> 
     <DataValue>CO12345</DataValue> 
    </ReturnItem> 
    <ReturnItem> 
     <DataName>ProductID</DataName> 
     <DataValue>XY000001</DataValue> 
    </ReturnItem> 
    </ReturnItems> 
</WebResult> 

但是,我不知道对皮卡SalesID的最好方式本例中CO12345的'DataValue'值。 (XML架构要大得多)

我可以解析SaleID + x字符的字符串,但如果Web服务发生变化,那我会依赖字符串位置。我宁愿不必序列化成一个类,因为它似乎应该有一个简单的方法来做到这一点。 (我错过了!)

+0

我编辑了你的标题。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 – 2013-05-13 01:03:04

如果你能够(或愿意)使用它,这很容易与LINQ to XML

' XDocument.Parse will load XML from a string 
' Use XDocument.Load to load it from a file 
Dim xDoc As XDocument = XDocument.Parse(xmlString) 

Dim salesID = (From x In xDoc.Descendants("ReturnItem") 
       Where x.Element("DataName").Value = "SaleID" 
       Select x.Element("DataValue").Value).FirstOrDefault() 

什么上面的代码片段确实是第一个获得在xDoc所有的“ReturnItem”元素(及其子女)。

接下来,它将SalesID作为值的“DataName”元素进行过滤。

然后它选择相应的“DataValue”元素的值。

FirstOrDefault返回匹配的第一个元素(或者如果找不到任何内容,则返回默认值)。如果没有FirstOrDefault(),您将得到一组匹配的结果,然后您可以重复执行。

以上是一个非常简单的例子,但是LINQ to XML功能非常强大,而我在处理XML时更喜欢它。

编辑以添加非LINQ APPROACH

这里有一种方法做上述使用XmlDocumentXPath syntax

Dim xmlDoc As New XmlDocument() 
' Use LoadXML to load from a string; if from a file use Load 
xmlDoc.LoadXml(xmlString) 

Dim SaleID As String 

Dim ReturnItems As XmlNodeList = xmlDoc.SelectNodes("/WebResult/ReturnItems/ReturnItem") 

For Each Item As XmlNode In ReturnItems 
    If Item.SelectSingleNode("DataName").InnerText = "SaleID" Then 
     SaleID = Item.SelectSingleNode("DataValue").InnerText 
    End If 
Next 

上面的代码片断加载XML字符串转换为XmlDocument。然后,它选择与XPath表达式“/ WebResult/ReturnItems/ReturnItem”匹配的所有节点(即它抓取所有ReturnItem节点及其子节点)。

接下来,它遍历集合,并为每个ReturnItem节点检查DataName节点是否等于“SaleID”,如果是,则将DataValue节点的值分配给SaleID字符串。

这又是一个微不足道的例子。如果您在XML中有多个“SaleID”节点,则需要将值放入列表或其他集合中,否则上述代码将只给出最后一个。

XPath功能非常强大,对XML和XPath的丰富支持自1.0版以来一直是.NET Framework的一部分。

这里的好处是,如果消息的格式发生变化,那么您只需要更新XPath查询,而不是解析如何解析新格式。

+0

谢谢蒂姆。 Linq肯定是要走的路,但由于我们无法控制的原因,我们在这个项目中坚持使用.NET Framework 2.0。 (框架与Linq不兼容,没有一些入侵。) – SSJON 2013-05-15 02:43:17

+0

@SSJON - 查看'XmlDocument'和XPath查询。我已经发布了一个简单的例子给你一个基本的想法。 – Tim 2013-05-15 05:26:55