Home > Blockchain >  XML/C#: Eeasiest way to delete elements with a specific attribute
XML/C#: Eeasiest way to delete elements with a specific attribute

Time:12-31

Xml:

<?xml version="1.0" encoding="UTF-8"?>
<Information>
  <Group Title="Abc">
    <Item Title="12" Visible="False">xxx</Item>
    <Item Title="34">xxx</Item>
  </Group>
  <Group Title="Def" Visible="False">
    <Item Title="56">xxx</Item>
  </Group>
  <Group Title="Ghi">
    <Item Title="78">xxx</Item>
    <Item Title="9">xxx</Item>
    <Item Title="10" Visible="False">xxx</Item>
  </Group>
</Information>

Want to delete all Groups (not only first or one!) and all (not only first or one!) Items with Visible=False, it teases me ...

With ex above, I want this result:

<?xml version="1.0" encoding="UTF-8"?>
<Information>
  <Group Title="Abc">
    <Item Title="34">xxx</Item>
  </Group>
  <Group Title="Ghi">
    <Item Title="78">xxx</Item>
    <Item Title="9">xxx</Item>
  </Group>
</Information>

This remove first but not all: x.Descendants("Group").Where(p => p.Attribute("Visible").Value == "False").First().Remove(); x.Descendants("Item").Where(p => p.Attribute("Visible").Value == "False").First().Remove();

For me it doesn't matter if I use XmlDocument or XDocument, but I try with Linq ...

Thanks for help/ideas ... there must be many options but ... a nice one :-)

CodePudding user response:

Please try the following solution.

It based on LINQ to XML.

As an alternative solution, it is very easy to achieve via XSLT.

Input XML file

<?xml version="1.0" encoding="UTF-8"?>
<Information>
    <Group Title="Abc">
        <Item Title="12" Visible="False">xxx</Item>
        <Item Title="34">xxx</Item>
    </Group>
    <Group Title="Def" Visible="False">
        <Item Title="56">xxx</Item>
    </Group>
    <Group Title="Ghi">
        <Item Title="78">xxx</Item>
        <Item Title="9">xxx</Item>
        <Item Title="10" Visible="False">xxx</Item>
    </Group>
    <Group Title="Def" Visible="False">
        <Item Title="56">xxx</Item>
    </Group>
</Information>

c#

void Main()
{
    const string inputXML = @"e:\Temp\MortenFredsgaardRasmussen.xml";
    const string outputXML = @"e:\Temp\MortenFredsgaardRasmussen_output.xml";

    XDocument xdoc = XDocument.Load(inputXML);

    xdoc.Descendants("Group")
        .Where(x => x.Attribute("Visible") != null)
        .Where(x => x.Attribute("Visible").Value.Equals("False"))
        .ToList()
        .ForEach(x => x.Remove());

    xdoc.Save(outputXML);
}

Output XML

<Information>
  <Group Title="Abc">
    <Item Title="12" Visible="False">xxx</Item>
    <Item Title="34">xxx</Item>
  </Group>
  <Group Title="Ghi">
    <Item Title="78">xxx</Item>
    <Item Title="9">xxx</Item>
    <Item Title="10" Visible="False">xxx</Item>
  </Group>
</Information>

CodePudding user response:

The following example uses the XmlDocument to delete required items:

var doc = new XmlDocument();
doc.Load(@"C:\Temp\doc.xml"));

var nav = doc.CreateNavigator();           
var nodes = nav.Evaluate(nav.Compile("//Group[@Visible='False'] | //Item[@Visible='False']"));

if (nodes is System.Xml.XPath.XPathNodeIterator iterator)
{
    var toDelete = new List<XPathNavigator>();
    foreach (XPathNavigator item in iterator)                
        toDelete.Add(item);                                    

    foreach (XPathNavigator item in toDelete)
        item.DeleteSelf();

    doc.Save(@"C:\Temp\result.xml");
}

The result is:

<?xml version="1.0" encoding="UTF-8"?>
<Information>
  <Group Title="Abc">
    <Item Title="34">xxx</Item>
  </Group>
  <Group Title="Ghi">
    <Item Title="78">xxx</Item>
    <Item Title="9">xxx</Item>
  </Group>
</Information>

For additional information see:

Use Visual C# to navigate XML documents with the XPathNavigator class

XPath Syntax

  • Related