尝试对按父元素名称和索引值过滤的命名 XML 元素进行计数

问题描述 投票:0回答:1

我一直在设法在 VB.net 中操作 XML,但我遇到了一个我真的很难解决的问题,所以我想寻求一些指导?!

使用此示例 XML...

<?xml version="1.0" encoding="utf-8"?>
<dataset>
  <packages>
    <package index="1">
      <desc>First Package</desc>
      <rmabool>1</rmabool>
      <rmaref>RMACASE1</rmaref>
      <bootfiles>1</bootfiles>
      <image>1</image>
      <driver>3</driver>
      <driver>4</driver>
    </package>
    <package index="2">
      <desc>Second Package</desc>
      <bootfiles>2</bootfiles>
      <image>2</image>
      <driver>3</driver>
    </package>
    <package index="3">
      <desc>Third Package</desc>
      <bootfiles>3</bootfiles>
      <image>2</image>
      <driver>3</driver>
    </package>
  </packages>
</dataset>

...我想计算索引匹配“1”的名为“package”的元素中包含有多少个名为“driver”的元素。我期望返回的结果是“2”,或者如果我更改搜索以匹配索引与“3”,那么我期望结果是“1”。

在其他地方,我有一个简单的子程序,它返回仅与名称匹配的元素计数,下面是我修改它的努力,但我无法让它工作......

Public Function CountElementDescendents(ByVal CFGFile As String,_ 'Path to Config.xml
                                        ByVal Parent As String,_ 'Name of element to search descendents eg. 'package'
                                        ByVal ParentIndex As String,_ 'Index value of element to search descendents eg. '1'
                                        ByVal ElementCount As String_ 'Name of descendent elements to count 'eg. 'driver'
                                        ) As Integer 'Return number of matching elements eg. '2'
    Dim ReturnValue As Integer = 0
    Dim Xe As XElement

    Xe = XElement.Load(CFGFile)
    Dim Query As IEnumerable(Of XElement) = Xe.Elements(Parent).Attribute("index="&ParentIndex).Descendants(ElementCount)
    
    ReturnValue = Query.Count()
    CountElementDescendents = ReturnValue
End Function

我不确定这是否可行,或者即使我已经采取了构建 XML 的最佳方法,有人可以提供一些帮助或建议吗?谢谢!

感谢@dbasnett 和@Craig 的帮助,你们太棒了!我会将其标记为已回答。

xml vb.net search linq-to-xml
1个回答
0
投票

尝试一下。 LINQ 查询检查所有驱动程序元素并选择其父级是索引为 1 的包的元素。

    'for testing use XML literal
    Dim xe As XElement
    xe = <dataset>
             <packages>
                 <package index="1">
                     <desc>First Package</desc>
                     <rmabool>1</rmabool>
                     <rmaref>RMACASE1</rmaref>
                     <bootfiles>1</bootfiles>
                     <image>1</image>
                     <driver>3</driver>
                     <driver>4</driver>
                 </package>
                 <package index="2">
                     <desc>Second Package</desc>
                     <bootfiles>2</bootfiles>
                     <image>2</image>
                     <driver>3</driver>
                 </package>
                 <package index="3">
                     <desc>Third Package</desc>
                     <bootfiles>3</bootfiles>
                     <image>2</image>
                     <driver>3</driver>
                 </package>
             </packages>
         </dataset>

    ' I would like to count how many elements, named 'driver', 
    '  are contained in an element named 'package' with an index matching "1". 
    '
    Dim ie As IEnumerable(Of XElement)
    ie = From el In xe...<driver>
         Where el.Parent.Name.LocalName = "package" AndAlso el.Parent.@index = "1"
         Select el

编辑:作为函数

Private Function Srch(ElementToSearch As XElement,
                         ParentName As String,
                         ParentIndex As String) As IEnumerable(Of XElement)

    Dim ie As IEnumerable(Of XElement)
    ie = From el In ElementToSearch...<driver>
         Where el.Parent.Name.LocalName = ParentName AndAlso el.Parent.@index = ParentIndex
         Select el

    Return ie

End Function

编辑2 - 更新功能

Private Function Srch(ElementToSearch As XElement,
                         FindThis As String,
                         ParentName As String,
                         ParentIndex As String) As IEnumerable(Of XElement)

    Dim ie As IEnumerable(Of XElement)

    ie = From el In ElementToSearch.Descendants(FindThis)
         Where el.Parent.Name.LocalName = ParentName AndAlso el.Parent.@index = ParentIndex
         Select el

    Return ie

End Function

测试

    Dim rslts As IEnumerable(Of XElement)
    rslts = Srch(xe, "bootfiles", "package", "1")
© www.soinside.com 2019 - 2024. All rights reserved.