使用LINQ读取XML数据,具有相同名称VB的多个元素

时间:2017-10-28 01:19:30

标签: xml vb.net visual-studio linq

我有一个包含多个同名节点的xml

<?xml version="1.0" encoding="UTF-8"?>
<Versions>
    <Version>
        <Trunk>GapGun Software Version 7.1</Trunk>
            <Branch>.142</Branch>
            <Branch>.145</Branch>
            <Branch>.148</Branch>
            <Branch>.153</Branch>
            <Branch>.176</Branch>
    </Version>
    <Version>
        <Trunk>GapGun Software Version 7.2</Trunk>
            <Branch>.142</Branch>
            <Branch>.145</Branch>
            <Branch>.148</Branch>
            <Branch>.153</Branch>
            <Branch>.176</Branch>
    </Version>
</Versions> 

我需要使用Trunk作为查询进行过滤时填充组合框到目前为止我有这个代码

Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim xelement As XElement = XElement.Load("F:\Test.xml")
    Dim Versions As IEnumerable(Of XElement) = xelement.Elements()
    For Each Version In Versions
        Console.WriteLine(Version.Element("Trunk").Value)
        ComboBox1.Items.Add(Version.Element("Trunk").Value)
    Next Version
End Sub

Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
    Dim xelement As XElement = XElement.Load("F:\Test.xml")
    Dim name =
        From nm In xelement.Elements("Version")
        Where CStr(nm.Element("Trunk")) = ComboBox1.Text
        Select nm
    For Each xEle As XElement In name
        Console.WriteLine(xEle)
        ComboBox2.Items.Add(xEle.Element("Branch").Value)
    Next xEle
End Sub
End Class

这个有效,但只返回第一个分支请帮助,我是一个完整的新手!

2 个答案:

答案 0 :(得分:0)

请尝试以下操作:

   Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim xdoc As XDocument = XDocument.Load(FILENAME)
        Dim versions As IEnumerable(Of XElement) = xdoc.Descendants("Version")
        For Each version As XElement In versions
            For Each trunk As XElement In version.Elements("Trunk")
                Console.WriteLine(CType(trunk, String))
                ComboBox1.Items.Add(CType(trunk, String))
            Next trunk

            For Each xEle As XElement In version.Elements("Branch")
                Console.WriteLine(CType(xEle, String))
                ComboBox2.Items.Add(CType(xEle, String))
            Next xEle
        Next version

    End Sub

答案 1 :(得分:0)

您的问题是您使用的方法XElement.Element将返回给定名称的一个(第一个)元素 从docs:获取具有指定XName的第一个(按文档顺序)子元素。

你需要改变代码来循环所有&#34;分支&#34;元素,您可以使用ComboBox.Items.AddRange方法

添加所有元素
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) _
        Handles ComboBox1.SelectedIndexChanged

    Dim xelement As XElement = XElement.Load("F:\Test.xml")
    Dim name =
        From nm In xelement.Elements("Version")
        Where CStr(nm.Element("Trunk")) = ComboBox1.Text
        Select nm

    For Each xEle As XElement In name
        Dim branches = xEle.Elements("Branch").Select(Function(el) el.Value).ToArray()

        Console.WriteLine(xEle)
        ComboBox2.Items.AddRange(branches)
    Next
End Sub

为了使代码更简单,只加载文件 - 您可以引入包含所有必需数据的Version类。
然后,您不需要搜索正确的主干,并将使用已有的分支机构。

Public Class Version
    Public Property Trunk As String
    Public Property Branches As List(Of String)
End Class

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim xelement As XElement = XElement.Load("F:\Test.xml")

    ' Create collection of versions
    Dim versions = _ 
        xelement.Elements().
                 Select(Function(version)
                           Return New Version With
                           {
                               .Trunk = version.Element("Trunk").Value
                               .Branches = version.Elements("Branch").
                                                   Select(Function(el) el.Value)
                           }
                        End Function)

    ' Bind collection of versions to ComboBox
    ' Name of property which will be used as displayed text
    ComboBox1.DisplayMember = "Trunk"
    ComboBox1.DataSource = versions
End Sub

然后,当用户选择中继填充分支时,组合框将更加简单

Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) _ 
        Handles ComboBox1.SelectionChangeCommitted

    Dim comboBox = DirectCast(sender, ComboBox)
    Dim selectedVersion = DirectCast(comboBox.SelectedItem, Version)

    ComboBox2.DataSource = selectedVersion.Branches
End Sub