我从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>
但是,在这个例子中,我不确定获取COID345的SalesID的'DataValue'值的最佳方法。 (XML模式更大)
我可以解析SaleID + x字符的字符串,但是如果Web服务发生了变化并且我依赖于字符串位置,那将会中断。我宁愿不必序列化到一个类,因为它似乎应该有一个简单的方法来做到这一点。 (我错过了!)
答案 0 :(得分:1)
如果您能够(或愿意)使用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方法
以下是使用XmlDocument
和XPath 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节点的值分配给{{1字符串。
这又是一个微不足道的例子。如果XML中有多个“SaleID”节点,则需要将值放在列表或其他集合中,否则上面的代码只会给出最后一个。
XPath非常强大,自1.0以来,对XML和XPath的丰富支持一直是.NET Framework的一部分。
这里的优点是,如果消息的格式发生变化,您只需要更新XPath查询,而不是弄清楚如何解析新格式。