如何检查特定父标签的所有子标签计数?

时间:2018-05-22 15:08:57

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

这是一个示例xml

<?xml version="1.0" encoding="utf-8"?>
<random>
  <chkr id="1">
    <ab>10.100.101.18</ab>
    <xy>5060</xy>
    <tt>pop</tt>
    <qq>pop</qq>
  </chkr>
  <chkr id="2">
    <ab>tarek</ab>
    <tt>tarek</tt>
    <ab>ffff</ab>
    <foo>pop</foo>
  </chkr>
  <chkr id="3">
    <ab>adf</ab>
    <foo>adf</foo>
    <tt>fadsf</tt>
    <ab>fadsf</ab>
    <tt>036</tt>
    <foo>.3</foo>
    <ssd>wolk</ssd>
  </chkr>
</random>

我想在每个父标记<ab>中搜索标记<tt><chkr>以外的标记,并获取该父节点中显示的标记的名称一旦。即在上面的示例xml中,输出应为<chkr id="3">多次包含标记<foo>

如何使用LINQ-TO-XML执行此操作?

1 个答案:

答案 0 :(得分:2)

按所有后代的名称分组是一个非常简单的解决方案: (x是您的XDocument的名称)

foreach (var e in x.Descendants("chkr"))
{
    foreach (var v in e.Descendants()
                       .Where(ee => ee.Name != "ab" && ee.Name != "tt")
                       .GroupBy(ee => ee.Name)
                       .Select(ee => new { Name = ee.Key, Count = ee.Count() }))
    {
        if (v.Count > 1)
            Console.WriteLine($"<chkr id={e.Attribute("id").Value}> contains the tag <{v.Name}> {v.Count} times.");
    }
}

使用您的XML,此代码将输出

  

<chkr id=3>包含标记<foo> 2次。

编辑:如果您想要评论中指定的结果,只需将您的代码更改为以下内容:

List<string> names = new List<string>();
List<int> counts = new List<int>();

foreach (var e in x.Descendants("chkr"))
{
    names = new List<string>();
    counts = new List<int>();

    foreach (var v in e.Descendants().Where(ee => ee.Name != "ab" && ee.Name != "tt").GroupBy(ee => ee.Name).Select(ee => new { Name = ee.Key, Count = ee.Count() }))
    {
        if (v.Count > 1)
        {
            names.Add(v.Name.ToString());
            counts.Add(v.Count);
        }
    }

    if (names.Any())
        Console.WriteLine($"<chkr id={e.Attribute("id").Value}> contains the tag/tags {String.Join(",", names)} {String.Join(",", counts)} times.");
}