Добавление элементов в ListView повторяет один и тот же элемент XML - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть поле списка, и я добавляю в него элементы. Но он дает мне одинаковый текст / элемент для элементов idAtt и applicationIDAtt в каждой строке. В des c обновляется новое значение для каждой строки.

Код

Public Sub loadFile()
    Dim doc As New XmlDocument()
    doc.Load(fileName)
    Dim LItem As New ListViewItem

    For Each node As XmlNode In doc.SelectNodes("/dmodule/content/faultIsolation/faultIsolationProcedure/faultDescr/descr")
        Dim idAtt = node.SelectSingleNode("//faultIsolationProcedure/@id").InnerText
        Dim desc As String = node.InnerText
        Dim applicIDAtt = node.SelectSingleNode("/dmodule/content/faultIsolation/faultIsolationProcedure/@applicRefId").InnerText

        Dim lv As ListViewItem = ListView1.Items.Add(idAtt)
        lv.SubItems.Add(desc)
        lv.SubItems.Add(applicIDAtt)
    Next
End Sub

Пример XML

<dmodule>
<content>
    <faultIsolation>
        <faultIsolationProcedure applicRefId="Software" id="tree1">
            <fault faultCode=" "/>
            <faultDescr>
                <descr>This nodes description</descr>
            </faultDescr>
        </faultIsolationProcedure>
    </faultIsolation>
</content>

1 Ответ

0 голосов
/ 28 февраля 2020

Ваши xpaths немного шаткие; вы на самом деле не рассматриваете документ как набор иерархических узлов. Если это помогает, думайте об этом как о путях к файлам и папках. Получите «папку» по определенному пути и извлеките ее атрибуты / внутренние тексты (файлы), но относитесь к ней относительно того, где вы находитесь

For Each node As XmlNode In doc.SelectNodes("/dmodule/content/faultIsolation/faultIsolationProcedure")
    Dim idAtt = node.Attributes("id").Value
    Dim desc As String = node.SelectSingleNode("faultDescr/descr").InnerText
    Dim applicIDAtt = node.Attributes("applicRefId").Value

Теперь вы действительно не опубликовали полезно большой XML образец документа для меня, чтобы точно определить, на каком уровне иерархии узлы повторяются, поэтому я предположил, что это так:

<dmodule> 
    <content>
        <faultIsolation>
            <faultIsolationProcedure applicRefId=""Software"" id=""tree1"">
                <fault faultCode="" ""/>
                <faultDescr>
                    <descr>This nodes description</descr>
                </faultDescr>
            </faultIsolationProcedure>

            <faultIsolationProcedure applicRefId=""Software2"" id=""tree2"">
                <fault faultCode="" ""/>
                <faultDescr>
                    <descr>This nodes description2</descr>
                </faultDescr>
            </faultIsolationProcedure>
        </faultIsolation>
    </content>
</dmodule>

1 faultIsolation узел имеет несколько faultIsolationprocedure узлов

Вот полный код, который вы можете вставить на какой-нибудь сайт vb. net fiddle и запустить, чтобы осветить проблему. Прочитайте полный код, включая мои комментарии. Я поместил свой код выше, а затем ваш код с комментарием к каждому, в комментариях в VB:

Imports System
Imports System.Xml

Public Module Module1



    Public Sub Main()

        Dim doc As New XmlDocument()
        doc.LoadXml("<dmodule> 
    <content>
        <faultIsolation>
            <faultIsolationProcedure applicRefId=""Software"" id=""tree1"">
                <fault faultCode="" ""/>
                <faultDescr>
                    <descr>This nodes description</descr>
                </faultDescr>
            </faultIsolationProcedure>

            <faultIsolationProcedure applicRefId=""Software2"" id=""tree2"">
                <fault faultCode="" ""/>
                <faultDescr>
                    <descr>This nodes description2</descr>
                </faultDescr>
            </faultIsolationProcedure>
        </faultIsolation>
    </content>
</dmodule>")

        '#####################################
        '                 my way
        '#####################################

        'treat /dmodule/content/faultIsolation/faultIsolationProcedure as a collection of nodes, do each one
        For Each node As XmlNode In doc.SelectNodes("/dmodule/content/faultIsolation/faultIsolationProcedure")

            'pull attribute by name
            Dim idAtt = node.Attributes("id").Value

            'pull a sub node relative to the current node, not the document root
            Dim desc As String = node.SelectSingleNode("faultDescr/descr").InnerText

            'pull attribute by name
            Dim applicIDAtt = node.Attributes("applicRefId").Value

            Console.WriteLine(idAtt)
            Console.WriteLine(desc)
            Console.WriteLine(applicIDAtt)

        Next

        Console.WriteLine("##############")

        '#####################################
        '              your way
        '#####################################
        For Each node As XmlNode In doc.SelectNodes("/dmodule/content/faultIsolation/faultIsolationProcedure/faultDescr/descr")

            'well it sort of works for the first one, because // is always the document root
            'in xpath, not the current node. The node you're looking at still knows of the
            'document and if you ask it to search for an xpath starting with // you're NOT
            'searching from the current node as a start point, but the doc root. this is why
            'you keep getting the same node, because the code goes back to the doc root and
            'pulls the first child node, which is always the same node!
            Dim idAtt = node.SelectSingleNode("//faultIsolationProcedure/@id").InnerText

            'this is OK - it works relative to the node you're currently on in the foreach
            'and it does return different descriptions each time
            Dim desc As String = node.InnerText

            'Again, this xpath starts with / which is "from the doc root" not "from the current node"
            '-because this doesn't have a double slash it has to be an exact path from the doc root
            'which is IS - it's a valid path and it might well be that there are lots of nodes
            'in the document with this path, but your call to selectsinglenode will only
            'give you the first encountered node in the document, so its always the same node..
            Dim applicIDAtt = node.SelectSingleNode("/dmodule/content/faultIsolation/faultIsolationProcedure/@applicRefId").InnerText
            Console.WriteLine(idAtt)
            Console.WriteLine(desc)
            Console.WriteLine(applicIDAtt)

        Next
    End Sub



End Module

Помните. Если у вас есть такая файловая система:

c:\temp\my\path\file.txt

Вы можете сделать это:

CD c:\temp\my

И вы будете в папке my, и вы можете обратиться к файл относительно или абсолютно:

notepad path\file.txt
notepad c:\temp\my\path\file.txt

XPath ничем не отличается; если вы начинаете путь с sla sh, он «из do c root» независимо от текущего узла, как если бы вы начинали путь к файлу с c:\, это с диска root независимо от текущего каталога

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...