I have an XML document like this:
400
In VB in case I need to find it again:
doc.Descendants().Where(Function(e) String.IsNullOrEmpty(e.Value)).Remove()
doc.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove();
This one line will not throw out empty parent tags that are full of empty children tags. It will just remove their children , which may or may not be appropriate in your situation. It is a really simple change to achieve this you simply have to start removing from the lowest level first. Something like
foreach(XElement child in doc.Descendants().Reverse())
{
if(!child.HasElements && string.IsNullOrEmpty(child.Value) && !child.HasAttributes) child.Remove();
}
Thanks Nyerguds for the attribute suggestion.
A single one-liner could do the job, no need to iterate over all elements. Here it goes:
doc.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove();
Tester
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
public class TestRemove
{
public static void Main() {
Console.WriteLine("----OLD TREE STARTS---");
XElement doc = XElement.Parse(@"<magento_api>
<data_item>
<code>400</code>
<message>Attribute weight is not applicable for product type Configurable Product</message>
</data_item>
<data_item>
<code>400</code>
<message>Resource data pre-validation error.</message>
</data_item>
<data_item>
<code>1</code>
<message></message>
</data_item>
<data_item>
<code></code>
<message>No code was given</message>
</data_item>
</magento_api>");
Console.Write(doc.ToString());
Console.WriteLine("");
Console.WriteLine("----OLD TREE ENDS---");
Console.WriteLine("");
doc.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove();
Console.WriteLine("----NEW TREE STARTS---");
Console.Write(doc.ToString());
Console.WriteLine("");
Console.WriteLine("----NEW TREE ENDS---");
Console.ReadKey();
}
}
}
And it also could be tested here