【问题标题】:Find value of attribute when value of sibling is known only仅当兄弟值已知时查找属性值
【发布时间】:2017-04-03 17:57:58
【问题描述】:

感谢一些很好的答案,我现在了解如何使用 LINQ to XML 在 XML 文件中查找元素。

我正在努力解决以下问题:要找到我只知道其兄弟值的属性的值:

<books>
    <book>
        <author>Douglas Adams</author>
        <title>The Hitch Hikers Guide to the Galaxy</title>
        <price>42</price>
        <locationId>1</locationId>
        <quantity>0</quantity>
    </book>
    <book>
        <author>Douglas Adams</author>
        <title>The Hitch Hikers Guide to the Galaxy</title>
        <price>42</price>
        <locationId>2</locationId>
        <quantity>7</quantity>
    </book>
    <book>
        <author>Douglas Adams</author>
        <title>The Hitch Hikers Guide to the Galaxy</title>
        <price>42</price>
        <locationId>3</locationId>
        <quantity>20</quantity>
    </book>
    <book>
        <author>Douglas Adams</author>
        <title>The Hitch Hikers Guide to the Galaxy</title>
        <price>42</price>
        <locationId>4</locationId>
        <quantity>5</quantity>
    </book>
</books>

如果我只知道位置 ID,我如何找到这本书的数量?假设我想要quantity 换成locationId = 3

我的方法是创建一个循环并在找到所需的位置 ID 后立即停止。这听起来像是最好的方法吗?有没有更简单的方法可以使用 LINQ to XML 完成此任务?

【问题讨论】:

    标签: c# xml linq linq-to-xml


    【解决方案1】:

    使用Descendants方法获取所有书籍,然后您可以使用Where扩展方法过滤并使用Select扩展项目。方法quantity:

    XDocument xdoc = XDocument.Load(path);
    var result=xdoc.Descendants("book")
                   .Where(e=>(int)e.Element("locationId")==3)
                   .Select(e=>(int)e.Element("quantity"))
                   .FirstOrDefault();
    

    【讨论】:

    • 代码有错字,docxdoc变量不一样
    【解决方案2】:

    首先,locationId 的结束标签有问题

    Linq-To-Xml 有一个NodesAfterSelf 方法,所以如果标签的顺序总是相同的,你可以使用:

    var quantityElement = xdoc.Descendants("locationId")
                 .First(l=>l.Value=="3")
                 .NodesAfterSelf()
                 .FirstOrDefault();
    

    编辑 -

    实际上,如果找不到位置,上述方法会引发异常。以下不会。

    var quantityElement = xdoc
                 .Descendants("locationId")
                 .Where(l=>l.Value=="3")
                 .SelectMany(l=>l.NodesAfterSelf())
                 .FirstOrDefault();
    

    【讨论】:

    • 谢谢@Ofir。这只是关于结束标签的错字。现在会修复它。
    【解决方案3】:

    对于可能需要此功能的 VB 用户。以下解决方案不对标签顺序进行假设。

        Dim xe As XElement
        'for testing
        xe = <books>
                 <book>
                     <author>Douglas Adams</author>
                     <title>The Hitch Hikers Guide to the Galaxy</title>
                     <price>42</price>
                     <locationId>1</locationId>
                     <quantity>0</quantity>
                 </book>
                 <book>
                     <author>Douglas Adams</author>
                     <title>The Hitch Hikers Guide to the Galaxy</title>
                     <price>42</price>
                     <locationId>2</locationId>
                     <quantity>7</quantity>
                 </book>
                 <book>
                     <author>Douglas Adams</author>
                     <title>The Hitch Hikers Guide to the Galaxy</title>
                     <price>42</price>
                     <locationId>3</locationId>
                     <quantity>20</quantity>
                 </book>
                 <book>
                     <author>Douglas Adams</author>
                     <title>The Hitch Hikers Guide to the Galaxy</title>
                     <price>42</price>
                     <locationId>4</locationId>
                     <quantity>5</quantity>
                 </book>
             </books>
    
        'the answer - by selecting the <book> all nodes are available.
        Dim aBook As XElement = xe...<book>.SingleOrDefault(Function(el) el.<locationId>.Value = "3")
    
        'verification
        If aBook IsNot Nothing Then
            Debug.WriteLine(aBook.<quantity>.Value)
            Debug.WriteLine(aBook.<author>.Value)
            Debug.WriteLine(aBook.<title>.Value)
        End If
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      • 2021-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多