Search code examples
c#xmlxmldocument

How to get latest node details by using xmldocument?


I have xml file like following.

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

I need only last latest update to print in xml.

I've used following xdocument(using system.xml.Linq) code and found output.

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");

The output came like following:

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

But instead of using xdocument Is there any option by getting this output by xmldocument(using system.xml)? I need output only by xmldocument.


Solution

  • You can do it manually. Just iterate through your Main elements from the end to beginning, removing any items which Name attribute has already been met.

    var document = new XmlDocument();
    document.LoadXml(xmlString);
    
    Dictionary<string, bool> used = new Dictionary<string, bool>();
    
    var allNodes = document.SelectNodes("Root/Main");
    
    for (int i = allNodes.Count - 1; i >= 0; i--)
    {
        var name = ((XmlElement)allNodes[i]).GetAttribute("Name");
    
        if (used.ContainsKey(name))
        {
            allNodes[i].ParentNode.RemoveChild(allNodes[i]);
        }
        else
        {
            used.Add(name, true);
        }
    }
    
    Console.WriteLine(document.OuterXml);
    

    Here is the working IDEOne demo.

    However, as I already mentioned in comments, it is a really good idea to use XDocument, because it is much more convenient, and it is modern.