仅当兄弟的值已知时查找属性值
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
感谢一些很好的回答,我现在明白了如何使用 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