XPath帮助,确切地说是XPathNodeIterator

时间:2012-02-07 16:18:38

标签: .net xml vb.net xpath

基本上我有一个如下所示的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<data>
<sender sndid="FT">
    <val n="name">Oy Finntack Ltd</val>
    <val n="address1">Keskikankaantie 29-31</val>
    <val n="zipcode">15860</val>
    <val n="city">Hollola</val>
    <val n="country">FI</val>
    <partner parid="POSTI">
        <val n="iban">FI2515193000110201</val>
        <val n="bic">NDEAFIHH</val>
        <val n="postgiro">15193000110201</val>
        <val n="custno">632368</val>
    </partner>
</sender>
<receiver rcvid="109480">
    <val n="name">Petra Kern</val>
    <val n="address1">Ziegelgasse 14</val>
    <val n="zipcode">73525</val>
    <val n="city">Schwabisch Gmund</val>
    <val n="country">DE</val>
</receiver>
<shipment orderno="635023">
    <val n="reference"/>
    <val n="from">FT</val>
    <val n="to">109480</val>
    <service srvid="IT14">
        <addon adnid="mprc"/>
        <val n="returnlabel">no</val>
    </service>
    <container measure="parcel" type="parcel">
        <val n="reference">PCK00000160</val>
        <val n="copies">1</val>
        <val n="weight">0.3</val>
        <val n="contents"/>
        <val n="packagecode">pc</val>
        <val n="marking">horze-finntack</val>
    </container>
</shipment>

我正在编写一个Windows服务,以给定的时间间隔检查文件夹中的XML文件,一次解析一个特定信息(地址,地址和货件内容),然后通过专有数据发送这些数据评估,运输和跟踪的方法。所有这些代码都运行正常,我的问题是在VB .Net中访问XML(我是一名PHP程序员,如果这是一个Web应用程序,可以在10分钟内完成)。无论如何,这里有一些代码。此子搜索PathExt结尾的所有文件,然后对于找到的每个文件,将从XML文件中获取某些信息并将其发送进行处理。

    Sub GetXMLFiles()
    //declare some variables
    Dim fName As String
    Dim Files = New ArrayList
    Dim I As Integer = 1
    Dim dirInfo As New DirectoryInfo(Path)
    Dim fileInfos() As FileInfo = dirInfo.GetFiles(Ext)
    For Each file_info As FileInfo In fileInfos
        fName = file_info.FullName
        Try
            Dim xDoc As XPathDocument = New XPathDocument(fName)
            Dim xNav As XPathNavigator = xDoc.CreateNavigator()

            //from here until the end of this Try statement is just a test.
            Dim sender As XPathNodeIterator
            sender = xNav.Select("/data/sender")
            While (sender.MoveNext())
                Console.WriteLine(sender.Current.Value)
            End While
            //end test

        Catch ex As Exception

        End Try
        Files.Add(Path & fName)
    Next file_info

End Sub

最后,这将是线程化的,因为XML结果将通过REST传输,处理每个请求所花费的时间是不确定的。

所以这是我的问题/问题。在我创建Navigator之后,我可以像测试中那样使用XPath表达式来选择某个节点。但是在我选择该节点后,我无法按名称访问其子节点。如果你注意到XML <sender>元素的属性没有正确命名,那么<val n="name">我需要返回的是每个<val>,它是<sender>的直接子项(为了我的目的,省略了<partner>部分。同样的事情适用于<receiver>元素。 <shipment>元素可能包含多个<container>元素,但是一旦我弄清楚如何正确返回所有内容,我就可以处理它。 <val>中每个<sender>所需要的是n="[NAME]"<val>的实际值。

如果您在提供的XML的<val>块中查看第一个<sender>,我希望有两个变量NameValue,对于第一个示例,是nameOy FinnTack Ltd

我知道我很亲密!很抱歉这篇文章很长,但我试图在stackoverflow上回答太多问题,因为这个人对他们想要做的事情非常模糊。

1 个答案:

答案 0 :(得分:1)

你几乎走在正确的轨道上。您想使用XPathNavigator.SelectChildren来完成此任务:

public virtual XPathNodeIterator SelectChildren(
    string name,
    string namespaceURI
)

我加载了您的示例XML文件,并使用以下代码对其进行处理:

Option Infer On
Option Explicit On
Option Strict On

Imports System.Xml
Imports System.Xml.XPath

Module Module1

    Sub Main()
        ParseXml("Test.xml")
        Console.ReadLine()
    End Sub

    Public Sub ParseXml(ByVal fn As String)
        Dim xd = New XPathDocument(fn)
        Dim xn = xd.CreateNavigator()

        Dim sender = xn.SelectSingleNode("/data/sender").SelectChildren("val", String.Empty)
        While (sender.MoveNext())
            Console.WriteLine("Name: {0}, Value: {1}", sender.Current.GetAttribute("n", String.Empty), sender.Current.Value)
        End While
    End Sub

End Module

输出如下:

Name: name, Value: Oy Finntack Ltd
Name: address1, Value: Keskikankaantie 29-31
Name: zipcode, Value: 15860
Name: city, Value: Hollola
Name: country, Value: FI