1

So,

I have this XPathDocument that I get back from a POST-request, and it basically looks like this:

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

This is way too much information, as I only need the following things: For every Message where the Topic node="GLTransaction" AND Message type=2, I need the Data KeyAlt and the Description.

The programming language is VB.NET.

Thanks a lot guys!

4

3 回答 3

1

The XPath that you need to to use to select the appropriate Message elements is:

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

For instance:

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

Or, by using 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
于 2013-04-10T15:55:51.153 回答
0

我想通了,类型和节点的过滤可以通过一个简单的 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
于 2013-04-10T15:57:02.290 回答
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
于 2013-04-10T15:57:33.860 回答