【问题标题】:Trying to count named XML elements filtered by parent element name and index value尝试计算按父元素名称和索引值过滤的命名 XML 元素
【发布时间】:2020-06-23 11:37:27
【问题描述】:

我一直在设法在 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>

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

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

Public Function CountElementDescendents(ByVal CFGFile As String,_ 'Path to Config.xml
                                        ByVal Perent 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(Perent).Attribute("index="&ParentIndex).Descendants(ElementCount)
    
    ReturnValue = Query.Count()
    CountElementDescendents = ReturnValue
End Function

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

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

【问题讨论】:

    标签: xml vb.net search xelement


    【解决方案1】:

    试试这个。 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")
    

    【讨论】:

    • 嗨 dbasnett,这太棒了,而且很管用,非常感谢!我只有最后一个问题,我已经修改了查询,所以我可以使用像 ie = From el In xe...&lt;driver&gt; Where (el.Parent.Name.LocalName = Perent AndAlso el.Parent.@index = ParentIndex) Select el 这样的子程序变量进行搜索,但我不确定如何从子程序外部传递“驱动程序”,这也可能吗?跨度>
    • 这看起来也不错,但如果我需要计算 'bootfiles' 而不是 'drivers' 会怎样?
    • 我不知道它是否可以在这种情况下工作,但是将内联代码转换为 XML 的常用方法通常是包含在 '' 中;我只对值这样做了,所以我不确定它对标签的工作方式是否相同。
    • 所以例如... In ElementToSearch...&lt;&lt;%= Parent %&gt;&gt;
    • 谢谢克雷格,这看起来像是我需要的那种解决方案,但是,我在使用该方法时遇到了“预期的 XML 名称”错误,抱歉。
    猜你喜欢
    • 2018-02-15
    • 2018-09-03
    • 2020-06-20
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多