仅当兄弟的值已知时查找属性值

Find value of attribute when value of sibling is known only

感谢一些很好的回答,我现在明白了如何使用 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 for locationId = 3.

我的方法是创建一个循环并在找到所需的位置 ID 后立即停止。这听起来像是最好的方法吗?使用 LINQ to XML?

是否有更简单的方法来完成此操作

使用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();

首先,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();

对于可能需要此功能的 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