[英]C# How to select all nodes of xml that have matching values
Below is an example of my starting xml and the xml result i'm trying to achieve. 以下是我尝试开始的xml和xml结果的示例。 What i'm trying to figure out is not how to create the desired xml but how to grab all matches nodes that have the same starting value.
我要找出的不是如何创建所需的xml,而是如何获取具有相同起始值的所有匹配节点。 For example below, you'll see the xml has apples, there are two nodes with apples.
例如,在下面的示例中,您将看到xml有苹果,有两个带有苹果的节点。 I want to find all those nodes and then create a custom xml afterwards.
我想找到所有这些节点,然后再创建一个自定义xml。
How do you loop for all nodes of an xml and then find all results on that same node level that have matching values? 如何循环查找xml的所有节点,然后在同一节点级别上找到具有匹配值的所有结果?
<?xml version="1.0"?>
<results>
<result>
<fruit>apples</fruit>
<price>0</price>
</result>
<result>
<fruit>pears</fruit>
<price>1</price>
</result>
<result>
<fruit>apples</fruit>
<price>2</price>
</result>
</results>
<?xml version="1.0"?>
<results>
<result>
<fruit>apples</fruit>
<prices>
<price>0</price>
<price>2</price>
</prices>
</result>
<result>
<fruit>pears</fruit>
<prices>
<price>1</price>
</prices>
</result>
</results>
You can accomplish this by using XDocument . 您可以使用XDocument完成此操作。 Do not forget to import.
不要忘记导入。
using System.Xml.Linq;
using System.Xml.XPath;
load document 载入文件
XDocument doc = XDocument.Load("C:\\t\\My File2.txt");
Create list that contains the array with the result elements 创建包含结果元素数组的列表
List<XElement[]> multipleElements = doc .XPathSelectElements("results/result") .GroupBy(result => result.Element("fruit").Value) .Select(groupContent => groupContent.ToArray()) .ToList();
=========== result =================== ===========结果===================
List [0] { apples,apples}
List [1] { pear }
XML I tested on: 我测试过的XML:
<?xml version="1.0"?> <results> <result> <fruit>apples</fruit> <price>0</price> </result> <result> <fruit>pears</fruit> <price>1</price> </result> <result> <fruit>apples</fruit> <price>2</price> </result> </results>
This VB code creates the desired output. 此VB代码创建所需的输出。 It selects as results and orders them by fruit value, and then a simple loop to create the desired output.
它选择结果作为结果并按水果值排序,然后进行简单循环以创建所需的输出。
Dim xe As XElement
' to load from a file
' Dim yourpath As String = "your path here"
'xe = XElement.Load(yourpath)
' for testing
xe = <results>
<result>
<fruit>apples</fruit>
<price>0</price>
</result>
<result>
<fruit>pears</fruit>
<price>1</price>
</result>
<result>
<fruit>apples</fruit>
<price>2</price>
</result>
</results>
Dim oxe As XElement = <results></results>
Dim rsltproto As XElement = <result>
<fruit></fruit>
<prices></prices>
</result>
Dim rslt As XElement
Dim fruit As String
'select all <result> order by fruit values
Dim allfruits As IEnumerable(Of XElement) = xe...<result>.OrderBy(Function(el) el.<fruit>.Value)
'simple loop to create new XML
For Each el As XElement In allfruits
If el.<fruit>.Value <> fruit Then
If rslt IsNot Nothing Then
oxe.Add(rslt)
End If
fruit = el.<fruit>.Value
rslt = New XElement(rsltproto)
rslt.<fruit>.Value = fruit
End If
rslt.<prices>.LastOrDefault.Add(el.<price>)
Next
If rslt IsNot Nothing Then
oxe.Add(rslt)
End If
' to save file
' xe.Save(yourpath)
This is a simple change to Timon's answer above 这是对上面Timon答案的简单更改
var doc = XDocument.Load(@"<path>\test.xml");
var fruitPrices = doc.XPathSelectElements("results/result")
.Select(d => new {
Fruit = d.Element("fruit").Value,
// TODO: parse to int if required
Price = d.Element("price").Value
})
.GroupBy(f => f.Fruit)
.Select(g => new {Fruit = g.Key, Prices = g.Select(x => x.Price)})
.ToList();
In LinqPad this gives 在LinqPad中,这给出了
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.