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