这是一个示例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执行此操作?
答案 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.");
}