如何使用c#从XML中删除类似的连续节点?

如何使用c#从XML中删除类似的连续节点?,c#,xml,linq-to-xml,C#,Xml,Linq To Xml,XML 我需要删除它的父节点下类似的连续的,输出应该是这样的 <A> <B id = "1"> <R> <C id="ABC" /> </B> <B id = "2" > <R> <C id="ABC" /> </B> <B id = "3" > <

XML


我需要删除它的父节点下类似的连续的
,输出应该是这样的

<A>
    <B id = "1">
        <R>
        <C id="ABC" />
    </B>
    <B id = "2" >
        <R>
        <C id="ABC" />
    </B>
    <B id = "3" >
        <R>
        <C id="XYZ" />
    </B>
    <B id = "4">
        <R>
        <C id="XYZ" />
    </B>
    <B id = "5">
        <R>
        <C id="QWE" />
    </B>
 </A>

如果这只能通过实用或使用LINQtoXML来实现,我就没有用了


感谢您的帮助:)

也许有一种更优雅的方法可以做到这一点,但这里有一种简单的方法:循环遍历所有
B
元素,并跟踪上一个
C
元素。这个示例是您所拥有的和一个更灵活的设计的混合,该设计使用字典,以防您在
a
下有多个类型的元素来跟踪。如果它真的像您的示例一样简单,那么就不要使用字典,只需使用
XElement-previousC

<A>
        <B id = "1">
            <R>
            <C id="ABC" />
        </B>
        <B id = "2">
            <R>
        </B>
        <B id = "3">
            <R>
            <C id="XYZ" />
        </B>
        <B id = "4">
            <R>
        </B>
        <B id = "5">
            <R>
            <C id="QWE" />
        </B>
</A>
//要使其在Linq to XML中工作,需要终止R节点
var xml=XDocument.Parse(@)
");
Dictionary previousCElements=新字典();
XElement current c,previousC;
foreach(xml.substands(“B”)中的var节点)
{
如果(!previousCElements.ContainsKey(node.Name.LocalName))
{
previousCElements[node.Name.LocalName]=node.Element(“C”);
}
其他的
{
previousC=PreviousElements[node.Name.LocalName];
currentC=节点元素(“C”);
if(先前的c.Attribute(“id”).Value.Equals(当前的c.Attribute(“id”).Value,StringComparison.InvariantCultureIgnoreCase))
{
当前c.Remove();
}
删除(node.Name.LocalName);
}
}
结果XML:

//to get this to work in Linq to XML, need to terminate the R nodes
var xml = XDocument.Parse(@"<A>
    <B id = ""1"">
        <R/>
        <C id=""ABC"" />
    </B>
    <B id = ""2"" >
        <R/>
        <C id=""ABC"" />
    </B>
    <B id = ""3"" >
        <R/>
        <C id=""XYZ"" />
    </B>
    <B id = ""4"">
        <R/>
        <C id=""XYZ"" />
    </B>
    <B id = ""5"">
        <R/>
        <C id=""QWE"" />
    </B>
 </A>");


 Dictionary<string, XElement> previousCElements = new Dictionary<string, XElement>();
 XElement currentC, previousC;

 foreach(var node in xml.Descendants("B"))
 {
    if (!previousCElements.ContainsKey(node.Name.LocalName))
    {
        previousCElements[node.Name.LocalName] = node.Element("C");
    }
    else
    {
        previousC = previousCElements[node.Name.LocalName];
        currentC = node.Element("C");
        if (previousC.Attribute("id").Value.Equals(currentC.Attribute("id").Value, StringComparison.InvariantCultureIgnoreCase))
        {
            currentC.Remove();
        }
        previousCElements.Remove(node.Name.LocalName);
    }
 }


你太棒了!谢谢:)ledbutter-如何只过滤将
作为其子对象的
?@user2729272在另一个问题中询问此问题并参考此问题
<A>
  <B id="1">
    <R />
    <C id="ABC" />
  </B>
  <B id="2">
    <R />
  </B>
  <B id="3">
    <R />
    <C id="XYZ" />
  </B>
  <B id="4">
    <R />
  </B>
  <B id="5">
    <R />
    <C id="QWE" />
  </B>
</A>