Как заполнить древовидную структуру из XML-файла несколькими дочерними узлами?

Я пытаюсь заполнить компонент TreeView в VB.NET из файла XML. Это большой файл XML, и я нарезал его, чтобы дать вам представление о том, как он структурирован. Я новичок в VB.NET, поэтому мне трудно понять это. Ниже приведено изображение порядка, в котором я ожидаю, что эти данные будут отображаться в TreeView, и я добавил несколько стрелок, чтобы вы могли понять, откуда данные должны поступать в структуре XML.

Я нашел и попытался адаптировать код из учебника Microsoft, но он основан на гораздо более простой структуре XML и не работает с моим файлом.

Стрелки на изображении отображаются не синхронно с тегами и узлами XML, но моя цель состояла в том, чтобы стрелки и прямоугольники не перекрывали друг друга, делая изображение нечитаемым.

Когда у нас есть узел с именем «Резак», это компонент другого типа, и в текущем узле «Резак» или «Держатель» может содержаться более одного узла, поэтому они разделены тегом «Ссылка». Если он называется «Держатель», это другой тип компонента в стеке инструментов... Каждый новый инструмент начинается с элемента с именем «Инструмент».

Под картинкой, что я пытаюсь сделать в коде:

Объяснение представления в виде дерева

Private Sub btnSearchTLS_Click(sender As Object, e As EventArgs) Handles btnSearchTLS.Click

        Try
            ' SECTION 1. Create a DOM Document and load the XML data into it.
            Dim dom As New XmlDocument()
            dom.Load(txtFileOpenTLS_2.Text)

            ' SECTION 2. Initialize the treeview control.
            tviewToolIDs.Nodes.Clear()
            tviewToolIDs.Nodes.Add(New TreeNode(dom.DocumentElement.Name))
            Dim tNode As New TreeNode()
            tNode = tviewToolIDs.Nodes(0)

            ' SECTION 3. Populate the TreeView with the DOM nodes.
            AddNode(dom.DocumentElement, tNode)
            tviewToolIDs.ExpandAll()

        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub AddNode(ByRef inXmlNode As XmlNode, ByRef inTreeNode As TreeNode)
        Dim xNode As XmlNode
        Dim tNode As TreeNode
        Dim nodeList As XmlNodeList
        Dim i As Integer

        ' Loop through the XML nodes until the leaf is reached.
        ' Add the nodes to the TreeView during the looping process.
        If inXmlNode.HasChildNodes() Then
            nodeList = inXmlNode.ChildNodes
            For i = 0 To nodeList.Count - 1
                xNode = inXmlNode.(i)
                inTreeNode.Nodes.Add(New TreeNode(xNode.Name))
                tNode = inTreeNode.Nodes(i)
                AddNode(xNode, tNode)
            Next
        Else
            ' Here you need to pull the data from the XmlNode based on the
            ' type of node, whether attribute values are required, and so forth.
            inTreeNode.Text = (inXmlNode.OuterXml).Trim
        End If
    End Sub

Вот файл XML:

    <?xml version="1.0"?>
<ToolLibrary Version="7.3">
    <Tools>
    <Tool ID="100004" Units="Millimeter">
      <Description>100004</Description>
      <Teeth>1</Teeth>
      <Type>Turning</Type>
      <Cutter>
        <Reference ID="12140 - N123G2-0318-0008">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Torneamento - Insertos paramétricos</ToolID>
          <EntityName>12140 - N123G2-0318-0008</EntityName>
          <Origin>
            <X>34.2</X>
            <Y>0</Y>
            <Z>-82.3</Z>
          </Origin>
          <Rotation>
            <X>0</X>
            <Y>-90</Y>
            <Z>0</Z>
          </Rotation>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
      </Cutter>
      <Holder>
        <Reference ID="12135 - C5-570-32-LF">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>12135 - C5-570-32-LF</EntityName>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="12139 - 570-32L123G18B130A">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>12139 - 570-32L123G18B130A</EntityName>
          <Origin>
            <X>21</X>
            <Y>0</Y>
            <Z>-42</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
      </Holder>
      <DrivenPoint ID="1">
        <Type>-1</Type>
        <Radius>0</Radius>
        <X>35</X>
        <Y>0</Y>
        <Z>-83.1</Z>
      </DrivenPoint>
      <DrivenPoint ID="2">
        <Type>-1</Type>
        <Radius>0</Radius>
        <X>31.82</X>
        <Y>0</Y>
        <Z>-83.1</Z>
      </DrivenPoint>
      <CutterCompensation ID="1">0.8</CutterCompensation>
      <CutterCompensation ID="2">0.8</CutterCompensation>
    </Tool>
    <Tool ID="100171" Units="Millimeter">
      <Description>100171</Description>
      <Teeth>1</Teeth>
      <Type>Turning</Type>
      <Cutter>
        <Reference ID="12349 - CNMG120412">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Torneamento - Insertos paramétricos</ToolID>
          <EntityName>12349 - CNMG120412</EntityName>
          <Origin>
            <X>-35.8</X>
            <Y>0</Y>
            <Z>-291.8</Z>
          </Origin>
          <Rotation>
            <X>0</X>
            <Y>-5</Y>
            <Z>0</Z>
          </Rotation>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
      </Cutter>
      <Holder>
        <Reference ID="11977 - C6-390.410-100-110A">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>11977 - C6-390.410-100-110A</EntityName>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="11978 - C6-570-2C-60-148-40L">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>11978 - C6-570-2C-60-148-40L</EntityName>
          <Origin>
            <X>0</X>
            <Y>0</Y>
            <Z>-110</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="11979 - SL-PCLNL-40-12HP">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>11979 - SL-PCLNL-40-12HP</EntityName>
          <Origin>
            <X>-10</X>
            <Y>0</Y>
            <Z>-258</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
      </Holder>
      <DrivenPoint ID="1">
        <Type>-1</Type>
        <Radius>0</Radius>
        <X>-37</X>
        <Y>0</Y>
        <Z>-293</Z>
      </DrivenPoint>
      <DrivenPoint ID="2">
        <Type>-1</Type>
        <Radius>0</Radius>
        <X>-37</X>
        <Y>0</Y>
        <Z>-293</Z>
      </DrivenPoint>
      <CutterCompensation ID="1">1.2</CutterCompensation>
      <CutterCompensation ID="2">1.2</CutterCompensation>
    </Tool>
    <Tool ID="100178" Units="Millimeter">
      <Description>100178</Description>
      <Teeth>8</Teeth>
      <Type>Milling</Type>
      <Cutter>
        <Reference ID="10084 - R90MT-12-05-RM">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Rotativas - Insertos Paramétricos</ToolID>
          <EntityName>10084 - R90MT-12-05-RM</EntityName>
          <Origin>
            <X>44</X>
            <Y>0</Y>
            <Z>-614</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="10084 - R90MT-12-05-RM1">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Rotativas - Insertos Paramétricos</ToolID>
          <EntityName>10084 - R90MT-12-05-RM</EntityName>
          <Origin>
            <X>31.112698</X>
            <Y>-31.112698</Y>
            <Z>-614</Z>
          </Origin>
          <Rotation>
            <X>0</X>
            <Y>0</Y>
            <Z>-45</Z>
          </Rotation>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="10084 - R90MT-12-05-RM11">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Rotativas - Insertos Paramétricos</ToolID>
          <EntityName>10084 - R90MT-12-05-RM</EntityName>
          <Origin>
            <X>31.112698</X>
            <Y>31.112698</Y>
            <Z>-614</Z>
          </Origin>
          <Rotation>
            <X>0</X>
            <Y>0</Y>
            <Z>45</Z>
          </Rotation>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="10084 - R90MT-12-05-RM12">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Rotativas - Insertos Paramétricos</ToolID>
          <EntityName>10084 - R90MT-12-05-RM</EntityName>
          <Origin>
            <X>0</X>
            <Y>-44</Y>
            <Z>-614</Z>
          </Origin>
          <Rotation>
            <X>0</X>
            <Y>0</Y>
            <Z>-90</Z>
          </Rotation>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="10084 - R90MT-12-05-RM13">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Rotativas - Insertos Paramétricos</ToolID>
          <EntityName>10084 - R90MT-12-05-RM</EntityName>
          <Origin>
            <X>0</X>
            <Y>44</Y>
            <Z>-614</Z>
          </Origin>
          <Rotation>
            <X>0</X>
            <Y>0</Y>
            <Z>90</Z>
          </Rotation>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="10084 - R90MT-12-05-RM14">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Rotativas - Insertos Paramétricos</ToolID>
          <EntityName>10084 - R90MT-12-05-RM</EntityName>
          <Origin>
            <X>-31.112698</X>
            <Y>31.112698</Y>
            <Z>-614</Z>
          </Origin>
          <Rotation>
            <X>0</X>
            <Y>0</Y>
            <Z>135</Z>
          </Rotation>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="10084 - R90MT-12-05-RM15">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Rotativas - Insertos Paramétricos</ToolID>
          <EntityName>10084 - R90MT-12-05-RM</EntityName>
          <Origin>
            <X>-44</X>
            <Y>0</Y>
            <Z>-614</Z>
          </Origin>
          <Rotation>
            <X>0</X>
            <Y>0</Y>
            <Z>180</Z>
          </Rotation>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="10084 - R90MT-12-05-RM">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Rotativas - Insertos Paramétricos</ToolID>
          <EntityName>10084 - R90MT-12-05-RM</EntityName>
          <Origin>
            <X>-31.1127</X>
            <Y>-31.1127</Y>
            <Z>-614</Z>
          </Origin>
          <Rotation>
            <X>0</X>
            <Y>0</Y>
            <Z>-135</Z>
          </Rotation>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
      </Cutter>
      <Holder>
        <Reference ID="11974 - C8-390.410-100 120A">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>11974 - C8-390.410-100 120A</EntityName>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="12001 - C8-391.01-80 065">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>12001 - C8-391.01-80 065</EntityName>
          <Origin>
            <X>0</X>
            <Y>0</Y>
            <Z>-120</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="12001 - C8-391.01-80 065">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>12001 - C8-391.01-80 065</EntityName>
          <Origin>
            <X>0</X>
            <Y>0</Y>
            <Z>-185</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="12002 - C8-391.05-CD-32-320">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>12002 - C8-391.05-CD-32-320</EntityName>
          <Origin>
            <X>0</X>
            <Y>0</Y>
            <Z>-250</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="10707 - FCM-D100-32-11">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>10707 - FCM-D100-32-11</EntityName>
          <Origin>
            <X>0</X>
            <Y>0</Y>
            <Z>-570</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
      </Holder>
      <DrivenPoint ID="1">
        <Type>-1</Type>
        <Radius>0</Radius>
        <X>0</X>
        <Y>0</Y>
        <Z>-620</Z>
      </DrivenPoint>
      <DrivenPoint ID="2">
        <Type>-1</Type>
        <Radius>0</Radius>
        <X>0</X>
        <Y>0</Y>
        <Z>-620</Z>
      </DrivenPoint>
      <CutterCompensation ID="1">50</CutterCompensation>
      <CutterCompensation ID="2">50</CutterCompensation>
    </Tool>
    <Tool ID="100192" Units="Millimeter">
      <Description>100192</Description>
      <Teeth>1</Teeth>
      <Type>Milling</Type>
      <Cutter>
        <Reference ID="10087 - 880-05-03-05H-C-GM">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Rotativas - Insertos Paramétricos</ToolID>
          <EntityName>10087 - 880-05-03-05H-C-GM</EntityName>
          <Origin>
            <X>-7.9</X>
            <Y>0</Y>
            <Z>-233.5</Z>
          </Origin>
          <Rotation>
            <X>0</X>
            <Y>0</Y>
            <Z>180</Z>
          </Rotation>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="10088 - 880-05 03 W05H-P-GM">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Rotativas - Insertos Paramétricos</ToolID>
          <EntityName>10088 - 880-05 03 W05H-P-GM</EntityName>
          <Origin>
            <X>12</X>
            <Y>0</Y>
            <Z>-233.5</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
      </Cutter>
      <Holder>
        <Reference ID="12007 - C4-390.410-100-090A">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>12007 - C4-390.410-100-090A</EntityName>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="12033 - 880-D2500C4-04">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>12033 - 880-D2500C4-04</EntityName>
          <Origin>
            <X>0</X>
            <Y>0</Y>
            <Z>-90</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
      </Holder>
      <DrivenPoint ID="1">
        <Type>-1</Type>
        <Radius>0</Radius>
        <X>0</X>
        <Y>0</Y>
        <Z>-234</Z>
      </DrivenPoint>
    </Tool>
    <Tool ID="801154" Units="Millimeter">
      <Description>801154</Description>
      <Teeth>1</Teeth>
      <Type>Turning</Type>
      <Cutter>
        <Reference ID="11325 - MKI-176807-13_4.4">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Torneamento - Insertos 3D</ToolID>
          <EntityName>11325 - MKI-176807-13_4.4</EntityName>
          <Origin>
            <X>-5.18</X>
            <Y>0</Y>
            <Z>-225</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
      </Cutter>
      <Holder>
        <Reference ID="12016 - 392.410-100-ASHL-32">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>12016 - 392.410-100-ASHL-32</EntityName>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
        <Reference ID="11328 - MKS-366807-18">
          <FileName>TBT_MASTER_LIBRARY.tls</FileName>
          <ToolID>Holders &amp; Acessorios</ToolID>
          <EntityName>11328 - MKS-366807-18</EntityName>
          <Origin>
            <X>-8</X>
            <Y>0</Y>
            <Z>-55</Z>
          </Origin>
          <NoSpin>0</NoSpin>
          <Alternate>Off</Alternate>
        </Reference>
      </Holder>
      <DrivenPoint ID="2">
        <Type>-1</Type>
        <Radius>0</Radius>
        <X>-2.980037</X>
        <Y>0</Y>
        <Z>-225</Z>
      </DrivenPoint>
      <DrivenPoint ID="1">
        <Type>-1</Type>
        <Radius>0</Radius>
        <X>-7.380037</X>
        <Y>0</Y>
        <Z>-225</Z>
      </DrivenPoint>
      <CutterCompensation ID="1">1.5</CutterCompensation>
      <CutterCompensation ID="2">1.5</CutterCompensation>
    </Tool>
  </Tools>
 </ToolLibrary>

Что мне нужно сделать в приведенном выше коде (учитывая, что это правильный код - не стесняйтесь придумывать новый подход), чтобы мой TreeView был заполнен, как показано на изображении?

Прошу прощения за вопрос, возможно, уже рассмотренный, я провел поиск и не смог найти что-то, что могло бы работать с моим примером XML.

Спасибо заранее,

Даниэль


person Daniel Santos    schedule 11.06.2015    source источник
comment
J, СПАСИБО БОЛЬШОЕ! Это сработало хорошо, и я многому научился из вашего кода!   -  person Daniel Santos    schedule 12.06.2015


Ответы (4)


Я улучшил вывод. См. код ниже

Imports System.Xml
Imports System.Xml.Linq
Imports System.IO
Imports System.Text.Encoding
Public Class Form1
    Const FILENAME As String = "c:\temp\test.xml"
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Try
            ' SECTION 1. Create a DOM Document and load the XML data into it

            Dim reader As New StreamReader(FILENAME, System.Text.Encoding.UTF8)
            Dim dom As XDocument = XDocument.Load(reader)            ' SECTION 2. Initialize the treeview control.
            TreeView1.Nodes.Clear()
            TreeView1.Nodes.Add(New TreeNode(dom.Root.Name.LocalName))
            Dim tNode As New TreeNode()
            tNode = TreeView1.Nodes(0)
            Dim tools As XElement = dom.Descendants("Tools").FirstOrDefault()
            ' SECTION 3. Populate the TreeView with the DOM nodes.
            AddNode(tools, tNode)
            TreeView1.CollapseAll()
            ExpandToLevel(TreeView1.Nodes, 1)


        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub AddNode(ByRef inXmlNode As XElement, ByRef inTreeNode As TreeNode)
        Dim elements As List(Of XElement)

        ' Loop through the XML nodes until the leaf is reached.
        ' Add the nodes to the TreeView during the looping process.
        If inXmlNode.Descendants.Count > 0 Then
            elements = inXmlNode.Descendants("Tool").ToList()
            For Each element As XElement In elements
                Dim ID As String = element.Attribute("ID").Value
                Dim Description As String = element.Element("Description").Value
                Dim Teeth As String = element.Element("Teeth").Value
                Dim Type As String = element.Element("Type").Value

                Dim newNode As TreeNode = inTreeNode.Nodes.Add(ID & " (" & String.Join(", ", {Description, "Teeth : " & Teeth, "Type : " & Type}) & ")")

                If Not element.Element("Cutter") Is Nothing Then
                    Dim Cutters As List(Of XElement) = element.Element("Cutter").Elements("Reference").ToList()
                    Dim CutterBranch As TreeNode = newNode.Nodes.Add("Cutter")
                    For Each Cutter As XElement In Cutters
                        Dim Cutter_ID As String = Cutter.Attribute("ID")
                        CutterBranch.Nodes.Add(Cutter_ID)
                    Next Cutter
                End If

                If Not element.Element("Holder") Is Nothing Then
                    Dim Holders As List(Of XElement) = element.Element("Holder").Elements("Reference").ToList()

                    Dim HolderBranch As TreeNode = newNode.Nodes.Add("Holder")
                    For Each Holder As XElement In Holders
                        Dim Holder_ID As String = Holder.Attribute("ID")
                        HolderBranch.Nodes.Add(Holder_ID)
                    Next Holder
                End If
            Next element
        Else
            ' Here you need to pull the data from the XmlNode based on the
            ' type of node, whether attribute values are required, and so forth.
            inTreeNode.Text = (inXmlNode.ToString()).Trim
        End If
    End Sub
    Sub ExpandToLevel(nodes As TreeNodeCollection, level As Integer)
        If level > 0 Then
            For Each node As TreeNode In nodes
                node.Expand()
                ExpandToLevel(node.Nodes, level - 1)
            Next node
        End If
    End Sub
    Sub treeView1_AfterExpand(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterExpand
        If Not e.Node.Parent Is Nothing Then
            e.Node.ExpandAll()
        End If
    End Sub

End Class
​
person jdweng    schedule 12.06.2015
comment
J, я сейчас попробую. Большое спасибо, я многому научился из вашего кода! - person Daniel Santos; 12.06.2015
comment
Он работает так, как ожидалось! Более того, я смог многому научиться из вашего кода! - person Daniel Santos; 12.06.2015
comment
Люди, которые управляют веб-сайтом, не одобрили бы все изменения, которые я сделал. Я отредактировал исходный ответ, но он не был одобрен. Поэтому я просто создал новый ответ. - person jdweng; 12.06.2015
comment
jdweng, у меня есть несколько XML-файлов, в которых элемент ‹Cutter› или разделы ‹Holder› не существуют. Когда ваш алгоритм сталкивается с ‹Инструментом› в этом сценарии, я получаю исключение Ссылка на объект, не установленную на экземпляр объекта. Это происходит либо с Dim Cutters As List(Of XElement) = element.Element(Cutter).Elements(Reference).ToList(), либо с Dim Holders As List(Of XElement) = element.Element(Holder).Elements(Reference). ToList() всякий раз, когда секции ‹держатель› или ‹резец› отсутствуют для данного элемента ‹Tool›. Как я могу пропустить, если их нет, и перейти к следующему «инструменту»? - person Daniel Santos; 12.06.2015
comment
Это сработало как шарм... У меня было другое исключение, вызванное аналогичной причиной, и ваш последний мод научил меня, как с этим справиться... Прошу прощения за беспокойство, потому что я определенно многое узнал об обработке XML из ваших примеров. ... - person Daniel Santos; 12.06.2015

Использовать это.

Const FILENAME As String = "C:\joy\Web.config.xml" Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Try ' РАЗДЕЛ 1. Создайте документ DOM и загрузите XML-данные в него

        Dim reader As New StreamReader(FILENAME, System.Text.Encoding.UTF8)
        Dim dom As XDocument = XDocument.Load(reader)            ' SECTION 2. Initialize the treeview control.
        Dim rootNode As New TreeNode(dom.Root.Name.LocalName)
        TreeView1.Nodes.Clear()
        TreeView1.Nodes.Add(rootNode)
        Dim ch = dom.Root.Elements()

        For Each obj As XElement In ch
            Dim chNode As New TreeNode(obj.Name.LocalName)
            addNode(obj, chNode, rootNode)
        Next

        rootNode.ExpandAll()

    Catch xmlEx As XmlException
        MessageBox.Show(xmlEx.Message)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub


Public Sub addNode(xmlParent As XElement, node As TreeNode, parentNode As TreeNode)
    parentNode.Nodes.Add(node)

    For Each item In xmlParent.Elements()
        Dim chNode As New TreeNode(item.Name.LocalName)
        If item.NodeType = XmlNodeType.Element Then
            For Each attr In item.Attributes
                chNode.Nodes.Add(New TreeNode(attr.Name.ToString() + " = " + attr.Value))
            Next
        End If
        addNode(item, chNode, node)
    Next
End Sub
person joy.sengupta    schedule 08.06.2017
comment
Пожалуйста, дополните свой ответ некоторыми пояснениями и исправьте отступ в верхней части блоков кода. Спасибо - person Clijsters; 08.06.2017

Я добавил немного фильтрации. Для этого я перешел с XmlDocument на linq XDocument. Я извлек кучу объектов в коде, но не поместил их все в древовидную структуру. Оставил это вам.

Imports System.Xml
Imports System.Xml.Linq
Imports System.IO
Imports System.Text.Encoding
Public Class Form1
    Const FILENAME As String = "c:\temp\test.xml"
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Try
            ' SECTION 1. Create a DOM Document and load the XML data into it

            Dim reader As New StreamReader(FILENAME, System.Text.Encoding.UTF8)
            Dim dom As XDocument = XDocument.Load(reader)            ' SECTION 2. Initialize the treeview control.
            TreeView1.Nodes.Clear()
            TreeView1.Nodes.Add(New TreeNode(dom.Root.Name.LocalName))
            Dim tNode As New TreeNode()
            tNode = TreeView1.Nodes(0)
            Dim tools As XElement = dom.Descendants("Tools").FirstOrDefault()
            ' SECTION 3. Populate the TreeView with the DOM nodes.
            AddNode(tools, tNode)
            TreeView1.ExpandAll()

        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub AddNode(ByRef inXmlNode As XElement, ByRef inTreeNode As TreeNode)
        Dim elements As List(Of XElement)
        Dim tNode As TreeNode
        Dim nodeList As XmlNodeList
        Dim i As Integer

        ' Loop through the XML nodes until the leaf is reached.
        ' Add the nodes to the TreeView during the looping process.
        If inXmlNode.Descendants.Count > 0 Then
            elements = inXmlNode.Descendants("Tool").ToList()
            For Each element As XElement In elements
                Dim ID As String = element.Attribute("ID").Value
                Dim Description As String = element.Element("Description").Value
                Dim Teeth As String = element.Element("Teeth").Value
                Dim Type As String = element.Element("Type").Value

                Dim CutterReference As XElement = element.Element("Cutter").Element("Reference")
                Dim Cutter_ID As String = CutterReference.Attribute("ID")
                Dim HolderReference As XElement = element.Element("Holder").Element("Reference")
                Dim Holder_ID As String = HolderReference.Attribute("ID")


                Dim newNode As TreeNode = inTreeNode.Nodes.Add(Description)
                newNode.Nodes.Add("Cutter :" & Cutter_ID)
                newNode.Nodes.Add("Holder :" & Holder_ID)


            Next element
        Else
            ' Here you need to pull the data from the XmlNode based on the
            ' type of node, whether attribute values are required, and so forth.
            inTreeNode.Text = (inXmlNode.ToString()).Trim
        End If
    End Sub
End Class
person jdweng    schedule 12.06.2015
comment
Привет jdweng, Спасибо за ваш быстрый ответ... На самом деле, теперь я получаю каждый узел, который не является тем, что я ищу... Я попытаюсь посмотреть, смогу ли я отфильтровать это... но я признаю, что Я понятия не имею, как это сделать... Спасибо! - person Daniel Santos; 12.06.2015

Я добавил сортировщик в код. Никогда не делал этого раньше. Думал, что это может упростить использование. Я отсортировал по типу инструмента (токарный, фрезерный) и количеству зубьев.

Imports System.Xml
Imports System.Xml.Linq
Imports System.IO
Imports System.Text.Encoding
Public Class Form1
    Const FILENAME As String = "c:\temp\test.xml"
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Try
            ' SECTION 1. Create a DOM Document and load the XML data into it

            Dim reader As New StreamReader(FILENAME, System.Text.Encoding.UTF8)
            Dim dom As XDocument = XDocument.Load(reader)            ' SECTION 2. Initialize the treeview control.
            TreeView1.Nodes.Clear()
            TreeView1.Nodes.Add(New Tool(dom.Root.Name.LocalName, Tool.NType.Root))
            Dim tNode As New Tool(False)
            tNode = TreeView1.Nodes(0)
            Dim tools As XElement = dom.Descendants("Tools").FirstOrDefault()
            ' SECTION 3. Populate the TreeView with the DOM nodes.
            AddNode(tools, tNode)
            TreeView1.TreeViewNodeSorter = NodeSorter.DefaultSorter
            TreeView1.Sort()
            TreeView1.CollapseAll()
            ExpandToLevel(TreeView1.Nodes, 1)


        Catch xmlEx As XmlException
            MessageBox.Show(xmlEx.Message)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub AddNode(ByRef inXmlNode As XElement, ByRef inTreeNode As Tool)
        Dim elements As List(Of XElement)

        ' Loop through the XML nodes until the leaf is reached.
        ' Add the nodes to the TreeView during the looping process.
        If inXmlNode.Descendants.Count > 0 Then
            elements = inXmlNode.Descendants("Tool").ToList()
            For Each element As XElement In elements

                Dim newTool As New Tool(Tool.NType.Tool)
                newTool.ID = element.Attribute("ID").Value
                newTool.Description = element.Element("Description").Value
                newTool.Teeth = element.Element("Teeth").Value
                newTool.Type = element.Element("Type").Value
                newTool.Text = newTool.ID & " (" & String.Join(", ", {newTool.Description, "Type : " & newTool.Type, "Teeth : " & newTool.Teeth}) & ")"

                inTreeNode.Nodes.Add(newTool)

                If Not element.Element("Cutter") Is Nothing Then
                    Dim Cutters As List(Of XElement) = element.Element("Cutter").Elements("Reference").ToList()
                    Dim newCutter As Tool = New Tool("Cutter", Tool.NType.Type)
                    newTool.Nodes.Add(newCutter)
                    For Each Cutter As XElement In Cutters
                        Dim Cutter_ID As String = Cutter.Attribute("ID")
                        newCutter.Nodes.Add(New Tool(Cutter_ID, Tool.NType.Part))
                    Next Cutter
                End If

                If Not element.Element("Holder") Is Nothing Then
                    Dim Holders As List(Of XElement) = element.Element("Holder").Elements("Reference").ToList()

                    Dim newHolder As Tool = New Tool("Holder", Tool.NType.Type)
                    newTool.Nodes.Add(newHolder)
                    For Each Holder As XElement In Holders
                        Dim Holder_ID As String = Holder.Attribute("ID")
                        newHolder.Nodes.Add(New Tool(Holder_ID, Tool.NType.Part))
                    Next Holder
                End If
            Next element
        Else
            ' Here you need to pull the data from the XmlNode based on the
            ' type of node, whether attribute values are required, and so forth.
            inTreeNode.Text = (inXmlNode.ToString()).Trim
        End If
    End Sub
    Sub ExpandToLevel(nodes As TreeNodeCollection, level As Integer)
        If level > 0 Then
            For Each node As TreeNode In nodes
                node.Expand()
                ExpandToLevel(node.Nodes, level - 1)
            Next node
        End If
    End Sub
    Sub treeView1_AfterExpand(sender As Object, e As TreeViewEventArgs) Handles TreeView1.AfterExpand
        If Not e.Node.Parent Is Nothing Then
            e.Node.ExpandAll()
        End If
    End Sub

End Class
Public Class Tool
    Inherits TreeNode

    Enum NType
        Root
        Tool
        Type
        Part
    End Enum

    Public NodeType As NType
    Sub New(type As NType)
        NodeType = type
    End Sub
    Sub New(text As String, type As NType)
        NodeType = Type
        Me.Text = text
    End Sub
    Private m_ID As String = ""
    Public Property ID As String
        Get
            Return m_ID
        End Get
        Set(value As String)
            m_ID = value
        End Set
    End Property

    Private m_Teeth As String = ""
    Public Property Teeth As String
        Get
            Return m_Teeth
        End Get
        Set(value As String)
            m_Teeth = value
        End Set
    End Property

    Private m_Type As String
    Public Property Type As String
        Get
            Return m_Type
        End Get
        Set(value As String)
            m_Type = value
        End Set
    End Property

    Private m_Description
    Public Property Description As String
        Get
            Return m_Description
        End Get
        Set(value As String)
            m_Description = value
        End Set
    End Property

    Public Function Add(text As String) As Tool
        Me.Text = text
        Return Me
    End Function

End Class
Public Class NodeSorter
    Implements IComparer

    Public Shared ReadOnly DefaultSorter As New NodeSorter

    'Create a node sorter that implements the IComparer interface. 
    'Compare the length of the strings, or the strings 
    'themselves, if they are the same length. 
    Public Function Compare(x As Object, y As Object) As Integer Implements System.Collections.IComparer.Compare

        Dim tx As Tool = CType(x, Tool)
        Dim ty As Tool = CType(y, Tool)

        If tx.NodeType = Tool.NType.Tool And ty.NodeType = Tool.NType.Tool Then
            'Compare the length of the strings, returning the difference. 
            If tx.Type.Length <> ty.Type.Length Then
                Return tx.Text.Length - ty.Text.Length
            End If

            'If they are the same length, call Compare.
            If tx.Type = ty.Type Then
                Return String.Compare(tx.Teeth, ty.Teeth)
            Else
                Return String.Compare(tx.Type, ty.Type)
            End If
        Else
            If tx.NodeType = Tool.NType.Part And ty.NodeType = Tool.NType.Part Then
                Return String.Compare(tx.Text, ty.Text)
            Else
                Return 0
            End If
        End If

    End Function
End Class
​
person jdweng    schedule 12.06.2015