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