简体   繁体   English

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

[英]How to remove similar consecutive nodes from XML using c#?

XML, 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>

I need to remove similar consecutive <C> under it's parent <B> node and the output should be something like, 我需要在其父<B>节点下删除相似的连续<C> ,并且输出应类似于

<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>

I'm not use if this can be achieved only pragmatically or using linq-to-xml. 如果只能通过务实或使用linq-to-xml来实现,则不会使用。

Any help appreciated :) 任何帮助表示赞赏:)

There may be a more elegant way to do this, but here is a simple way of doing it: by looping through all your B elements and keeping track of the previous C element. 可能有一种更优雅的方法来执行此操作,但这是一种简单的方法:通过遍历所有B元素并跟踪先前的C元素。 This sample is a hybrid between what you have and a little more flexible design that uses a dictionary in case you have more than one type of element under A to keep track of. 该示例是您所拥有的内容与稍微灵活一些的设计之间的混合体,如果您在A下要跟踪A以上的元素,则可以使用字典。 If it really is as simple as your example, get rid of the dictionary and just use XElement previousC . 如果确实像您的示例一样简单,则摆脱字典,而只需使用XElement previousC

//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);
    }
 }

Resulting XML: 产生的XML:

<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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM