Search code examples
xmllinqlinq-to-xmlxmldocument

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


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


Solution

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