【问题标题】:Get specific nodes from XPathDocument从 XPathDocument 获取特定节点
【发布时间】:2013-04-02 12:46:26
【问题描述】:

所以,

我有一个从 POST 请求返回的 XPathDocument,它基本上看起来像这样:

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

这信息太多了,因为我只需要以下内容: 对于 Topic node="GLTransaction" AND Message type=2 的每个 Message,我需要 >Data KeyAlt描述

编程语言是 VB.NET。

非常感谢大家!

【问题讨论】:

  • 你的问题让我很困惑。你是说你从 POST 请求中取回了那个 XML 文档 并且你正在尝试使用 XPathDocument 类来读取它?
  • 是的,与此同时,我已经找到了答案,将在这里发布。

标签: xml vb.net xpath


【解决方案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

【讨论】:

  • 谢谢 :) 已经想通了,但你的答案也是正确的。
【解决方案2】:

应该这样做:

' 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

【讨论】:

    【解决方案3】:

    我想通了,类型和节点的过滤可以通过一个简单的 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-29
      • 1970-01-01
      相关资源
      最近更新 更多