如何删除xml中重复的节点详细信息

本文关键字:节点 详细信息 xml 何删除 删除 | 更新日期: 2023-09-27 18:25:04

我有如下的xml文件。

<Root>
      <Main Name="Install">
        <Details>Success</Details>
        <Maintain>Install period</Maintain>
      </Main>
    <Main Name="Uninstall">
        <Details>failure</Details>
        <Maintain>uninstall period</Maintain>
      </Main>
     <Main Name="Discard">
        <Details>failure</Details>
        <Maintain>discard period</Maintain>
      </Main>
     <Main Name="Install">
        <Details>Done</Details>
        <Maintain>Got Output</Maintain>
      </Main>
    </Root>

我只需要最后一次更新就可以用xml打印了。

我使用了以下代码并找到了输出。

XDocument xDoc1 = XDocument.Load(inputFileName);
        var elems = xDoc1.Element("Root").Elements("Main");
        XElement xInstall = elems.LastOrDefault(a => a.Attribute("Name").Value == "Install");
        XElement xUninstall = elems.LastOrDefault(a => a.Attribute("Name").Value == "Uninstall");
        XElement xDiscard = elems.LastOrDefault(a => a.Attribute("Name").Value == "Discard");
        XDocument xdoc2 = new XDocument();
        xdoc2.Add(
            new XElement("Root", new XElement[]
            {
                xInstall,
                xDiscard,
                xUninstall
            })
        );
        xdoc2.Save(ouputFileName);

但是,当在foreach循环中使用相同的逻辑时,我无法获得正确的输出。我的代码是

XmlDocument xml = new XmlDocument();
string xmlLocation = @"C:'Input.xml";
xml.Load(xmlLocation);
XmlNodeList MainNameList = xml.SelectNodes("/Root/Main");
XDocument xDoc1 = XDocument.Load(@"C:'Input.xml");
var elems = xDoc1.Element("Root").Elements("Main");
XDocument xdoc2 = new XDocument();
xdoc2.Add(new XElement("Root"));
foreach (XmlNode MainNode in MainNameList)
{
    string mainName = MainNode.Attributes[0].Value;
    XElement MainNode = elems.LastOrDefault(a => a.Attribute("Name").Value == mainName);

    xdoc2.Root.Add(new XElement("Root", new XElement(MainNode)));
}
xdoc2.Save(@"C:'Output.xml");

输出如下:

<Root>
  <Main Name="Install">
    <Details>Success</Details>
    <Maintain>Naveen</Maintain>
  </Main>
  <Main Name="Uninstall">
    <Details>failure</Details>
    <Maintain>uninstall period</Maintain>
  </Main>
  <Main Name="Discard">
    <Details>failure</Details>
    <Maintain>discard period</Maintain>
  </Main>
  <Main Name="Install">
    <Details>Success</Details>
    <Maintain>Naveen</Maintain>
  </Main>
</Root>

但我需要输出如下:

<Root>
 <Main Name="Uninstall">
   <Details>failure</Details>
    <Maintain>uninstall period</Maintain>
 </Main>
 <Main Name="Discard">
    <Details>failure</Details>
    <Maintain>discard period</Maintain>
 </Main>
<Main Name="Install">
    <Details>Done</Details>
    <Maintain>Got Output</Maintain>
 </Main>
</Root>

我的代码有什么错误?请帮助我通过使用foreach循环获得正确的输出。因为我的xml中有很多主要元素。提前谢谢。

如何删除xml中重复的节点详细信息

原因是每次找到名为"X"的元素时,只需输出最后一个名为"X"的元素。但是,您不记得是否输出了它。

您可以简单地通过使用List<string>并记住已输出的项目来完成此操作。

同时,通过对LINQ进行通用化,对项目进行分组,并从每组中提取最后一个项目,可以很容易地实现这一结果:

XDocument xDoc1 = XDocument.Load(@"C:'Input.xml");
var elemsNew = xDoc1.Element("Root").Elements("Main")
    .GroupBy(x => x.Attribute("Name").Value)
    .Select(g => g.Last())
    .ToArray();
XDocument xDoc2 = new XDocument(new XElement("Root", elemsNew));
xDoc2.Save(@"C:'Output.xml");

如果xml中有任何重复的节点(属性名称重复),下面的代码片段将忽略所有重复的元素,并选择最后一个元素。

XmlDocument xml = new XmlDocument();
string xmlLocationInput = @"C:'Users'jprabadiya'Desktop'Input.xml";
string xmlLocationOutput = @"C:'Users'jprabadiya'Desktop'Output.xml";
xml.Load(xmlLocationInput);
XDocument xDoc1 = XDocument.Load(xmlLocationInput);
var elems = xDoc1.Element("Root").Elements("Main"); 
var nodeList = elems.GroupBy(d => d.Attribute("Name").Value).Select(d => d.Last()).ToList();
XDocument xdoc2 = new XDocument();
xdoc2.Add(new XElement("Root"));
xdoc2.Root.Add(nodeList);
xdoc2.Save(xmlLocationOutput);

输出:

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <Main Name="Install">
    <Details>Done</Details>
    <Maintain>Got Output</Maintain>
  </Main>
  <Main Name="Uninstall">
    <Details>failure</Details>
    <Maintain>uninstall period</Maintain>
  </Main>
  <Main Name="Discard">
    <Details>failure</Details>
    <Maintain>discard period</Maintain>
  </Main>
</Root>

您使用的是两个不同的XML库,我将把它简化为Linq2XML。

XDocument xDoc1 = XDocument.Load(@"C:'Input.xml");
var elems = xDoc1.Descendants("Main");
// Get all the main names in the input file (1 of each)
string[] names = elems
    .Select(main => main.Attribute("Name").Value)
    .Distinct()
    .ToArray();
XDocument xdoc2 = new XDocument();
XElement root;
xdoc2.Add(root = new XElement("Root"));
foreach (string name in names)
{
    XElement node = elems
        .LastOrDefault(a => a.Attribute("Name").Value == name);
    root.Add(new XElement(node));
}
xdoc2.Save(@"C:'Output.xml");