从XPathDocument获取特定节点

时间:2013-04-10 15:16:49

标签: xml vb.net xpath

所以,

我有这个 XPathDocument ,我从POST请求中回来了,它基本上是这样的:

<eExact xsi:noNamespaceSchemaLocation="eExact-XML.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">    
  <Messages>      
    <Message type="0">        
      <Topic code="GLTransactions" node="GLTransaction">          
        <Data keyAlt="138100138" />        
      </Topic>        
      <Date>2013-04-10T16:57:00</Date>        
      <Description> Topic [GLTransactions] Bestaat reeds - Boekstuknummer: 138100138, Dagboek: 81, Boekjaar: 2013</Description>      
    </Message>      
    <Message type="2">        
      <Topic code="GLTransactions" node="Account">          
        <Data keyAlt="577" />        
      </Topic>        
      <Date>2013-04-10T16:57:00</Date>        
      <Description>Bijgewerkt</Description>     
    </Message>      
    <Message type="2">        
      <Topic code="GLTransactions" node="GLTransaction">          
        <Data keyAlt="138100140" />        
      </Topic>        
      <Date>2013-04-10T16:57:00</Date>        
      <Description>Aangemaakt</Description>      
    </Message>    
  </Messages>  
</eExact>

这是太多的信息,因为我只需要以下内容: 对于每个消息,其中主题节点=“GLTransaction” AND 消息类型= 2 ,我需要 Data KeyAlt 说明

编程语言是VB.NET。

非常感谢你们!

3 个答案:

答案 0 :(得分:1)

您需要用来选择适当的Message元素的XPath是:

//Message[(Topic/@node='GLTransaction') and (@type='2')]

例如:

Dim doc As New XPathDocument("test.xml")
Dim nav As XPathNavigator = doc.CreateNavigator()
Dim iter As XPathNodeIterator = nav.Select("//Message[(Topic/@node='GLTransaction') and (@type='2')]")
While iter.MoveNext
    Dim keyAlt As String = iter.Current.SelectSingleNode("Topic/Data/@keyAlt").Value
    Dim description As String = iter.Current.SelectSingleNode("Description").Value
End While

或者,使用XmlDocument

Dim doc As New XmlDocument()
doc.Load("test.xml")
For Each message As XmlNode In doc.SelectNodes("//Message[(Topic/@node='GLTransaction') and (@type='2')]")
    Dim keyAlt As String = message.SelectSingleNode("Topic/Data/@keyAlt").InnerText
    Dim description As String = message.SelectSingleNode("Description").InnerText
Next

答案 1 :(得分:0)

我想通了,可以使用easy if语句完成对类型和节点的过滤:

    Dim xml As New XPathDocument(stream)
    Dim nav As XPathNavigator = xml.CreateNavigator()
    Dim Messages As XPathNodeIterator = nav.Select("/eExact/Messages/Message")
    Dim exactID As String
    Dim topic As String
    Dim description As String

    Dim bErrorsFound As Boolean = False

    If Messages.Count > 0 Then
        While Messages.MoveNext()
            nav = Messages.Current
            errorCode = nav.GetAttribute("type", String.Empty)

            topic = nav.Evaluate("string(Topic/@node)")
            exactID = nav.Evaluate("string(Topic/Data/@keyAlt)")
            description = nav.Evaluate("string(Description)")

        End While
    End If

答案 2 :(得分:0)

这应该这样做:

' A class to contain both values
Public Class Obj
    Public Property DataKeyAlt As String
    Public Property Description As String
End Class

' A method to parse the XML and return your data
Public Function GetData(Xml as String) as IEnumerable(Of Obj)
    Dim doc As XDocument = XDocument.Parse(xml)

    return From el As XElement In doc...<Message> _
           Where el...<Topic>.First.@node = "GLTransaction" AndAlso el.@type = "2" _
           Select New Obj With { _
                   .DataKeyAlt = el...<Data>.@keyAlt, _
                   .Description = el...<Description>.Value}
End Function