簡體   English   中英

在XML中返回不同的路徑

[英]Returning distinct paths in XML

我有一個XML文件,我想從中檢索所有唯一路徑。 在以下示例中:

<?xml version="1.0" encoding="utf-8"?>
<views>
    <invoice>
        <newRa elem="0">
            <createD>20150514</createD>
            <modD>1234</modD>
            <sample>text</sample>
        </newRa>
        <total>1.99</total>
    </invoice>
</views>

我想要檢索:

views/invoice/newRa/createD
views/invoice/newRa/modD
views/invoice/newRa/sample

and so on......

我對xPath有一些經驗,但我不確定如何開始在VB中設置一個sub來為我做這個。 請注意,我正在使用.NET 2.0,因此LINQ是不可能的。

編輯1:

Dim xOne As New XmlDocument
xOne.Load("d/input/oneTest.xml")

For Each rNode As XmlNode In xOne.SelectSingleNode("/")
    If rNode.HasChildNodes Then
        subHasChild(rNode)
    End If
Next



Private Sub subHasChild(ByVal cNode As XmlNode)
    Dim sNode = cNode.Name

    If cNode.HasChildNodes Then
        sNode = sNode + "/" + cNode.FirstChild.Name
        cNode = cNode.FirstChild
        subHasChild(cNode)
    End If

    Dim sw As New StreamWriter("d:\input\paths.txt")
    sw.WriteLine(sNode)
    sw.Flush() : sw.Close() : sw.Dispose()
End Sub

嘗試這個:

    Dim xd = <?xml version="1.0" encoding="utf-8"?>
<views>
    <invoice>
        <newRa elem="0">
            <createD>20150514</createD>
            <modD>1234</modD>
            <sample>text</sample>
        </newRa>
        <total>1.99</total>
    </invoice>
</views>

    Dim getPaths As Func(Of XElement, IEnumerable(Of String)) = Nothing
    getPaths = Function(xe) _
        If(xe.Elements().Any(), _
            xe.Elements() _
                .SelectMany( _
                    Function(x) getPaths(x), _
                    Function(x, p) xe.Name.ToString() + "/" + p) _
                .Distinct(), _
            { xe.Name.ToString() })

    Dim paths = getPaths(xd.Root)

它給了我:

views/invoice/newRa/createD 
views/invoice/newRa/modD 
views/invoice/newRa/sample 
views/invoice/total 

它正確地擺脫了重復的路徑。

感謝所有回復的人。 在研究了各種方法之后,我最終使用字典來獲得所有獨特的路徑。 對於任何可能遇到類似情況的人來說,這是我使用的:

Dim xdDoc As New SmlDocument
Dim sw As New StreamWriter("Output File Path")
Dim diElements As New Dictionary(Of String, Integer)

xdDoc.Load("File Path")

For Each rootNode As XmlNode In xdDoc.SelectNodes("//*")
            Dim sNode As String = rootNode.Name

            While Not rootNode.ParentNode Is Nothing _
            AndAlso Not rootNode.ParentNode.Name Is "invoice" _
            AndAlso Not rootNode.ParentNode.Name Is "#document"
                rootNode = rootNode.ParentNode
                sNode = rootNode.Name + "/" + sNode
            End While

            If Not diElements.ContainsKey(sNode) Then
                diElements.Add(sNode, 1)
            Else
                diElements(sNode) += 1
            End If
        Next
    End While

    Dim pair As KeyValuePair(Of String, Integer)
    For Each pair In diElements
        sw.WriteLine("{0} --- {1}", pair.Value, pair.Key)
    Next

    sw.Flush() : sw.Close() : sw.Dispose()

這比我想象的要糟糕得多。 我不是一個優秀的程序員,但我通常可以弄清楚如何完成它,但我的代碼通常用於小型實用程序的非常有限的使用,所以它只需要工作。

注意:現在已更新為僅輸出唯一路徑

Private PathArray As New ArrayList

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Dim xDoc As New XmlDocument
    Dim Output As String = ""

    xDoc.Load("C:\inetpub\wwwroot\SqlMonitor\MonitorConfig.xml")
    NodeRecurser(xDoc.SelectSingleNode("/"))

    For Each item In PathArray
        Output += item & vbCrLf
    Next

    MsgBox(Output)

    Me.Close()

End Sub

Sub NodeRecurser(xNode As XmlNode)

    If xNode.HasChildNodes Then

        For Each cNode As XmlNode In xNode.ChildNodes

            NodeRecurser(cNode)

        Next

    Else : GetPath(xNode)

    End If

End Sub

Sub GetPath(n As XmlNode)

    Dim xPath As String = ""

    Do

        If n.ParentNode.Name <> "#document" Then

            xPath = n.ParentNode.Name & "/" & xPath
            n = n.ParentNode

        Else : Exit Do

        End If

    Loop

    If xPath.Length > 1 And Not PathArray.Contains(xPath) Then PathArray.Add(xPath)

End Sub

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM