C#如何选择具有匹配值的xml的所有节点

时间:2017-06-17 20:31:10

标签: c# xml linq-to-xml

以下是我尝试实现的启动xml和xml结果的示例。我想弄清楚的不是如何创建所需的xml,而是如何获取具有相同起始值的所有匹配节点。例如下面,您将看到xml有苹果,有两个苹果节点。我想找到所有这些节点,然后创建一个自定义xml。

如何循环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>

3 个答案:

答案 0 :(得分:0)

您可以使用XDocument完成此操作。别忘了导入。

 using System.Xml.Linq;
 using System.Xml.XPath;

加载文件

      XDocument doc = XDocument.Load("C:\\t\\My File2.txt");
  1. 选择所有结果元素
  2. 按果实值分组,例如3个苹果1个梨子
  3. 将结果元素从组中添加并添加到数组中
  4. 创建包含带有结果元素

    的数组的列表
          List<XElement[]> multipleElements = doc
            .XPathSelectElements("results/result")
            .GroupBy(result => result.Element("fruit").Value)
            .Select(groupContent => groupContent.ToArray())
            .ToList();
    
  5. ===========结果===================

     List [0] { apples,apples} 
     List [1] { pear }
    

    我测试过的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>

答案 1 :(得分:0)

此VB代码创建所需的输出。它选择结果并按果实值排序,然后用一个简单的循环来创建所需的输出。

    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)

答案 2 :(得分:0)

这是对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();

在LinqPad中,这给了

enter image description here