仅在知道兄弟的值时查找属性的值

时间:2017-04-03 17:57:58

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

感谢一些很好的答案,我现在了解如何使用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,我怎么能找到这本书的数量?假设我希望quantitylocationId = 3

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

3 个答案:

答案 0 :(得分:2)

使用 1 2 3 _ _ _ _ _ _ | | | | |_ _|_ _|_ _| 1 | | | | |_ _|_ _|_ _| 2 方法获取所有图书,然后您可以使用Descendants扩展方法和项目Where分机进行过滤。方法Select

quantity

答案 1 :(得分:1)

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

答案 2 :(得分:1)

对于可能需要此功能的VB'ers。以下解决方案不会对标记顺序进行假设。

    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