I have an XML document like this:
<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>
I'm trying to iterate each node and do the following:
The part I'm struggling with is how to iterate through each node and check each element for null values.
I've been testing this code out at http://rextester.com/runcode but can't seem to figure it out:
Console.WriteLine("Querying tree loaded with XElement.Load");
Console.WriteLine("----");
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>");
int counter = 1;
IEnumerable<XNode> nodes =
from nd in doc.Nodes()
select nd;
foreach (XNode node in nodes)
{
Console.WriteLine(counter + "-" + node);
IEnumerable<XElement> elements =
from el in node //this is where I've been trying various methods, but no dice.
select el;
foreach (XElement e in elements)
{
Console.WriteLine(counter + "-" + e.Name + "-" + e.Value + "\r\n");
}
counter++;
}
Based on the above XML input, I'm hoping to get the following output:
<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>
</data_item>
<data_item>
<message>No code was given</message>
</data_item>
</magento_api>
I'm not sure if I'm using the right methods to iterate over the nodes and elements.
You can to remove empty XML tags from messages for optimization. For example, an XML representation of an integration object might have unused integration components. You can use the siebel_ws_param:RemoveEmptyTags parameter to remove empty tags when making Web service calls.
An empty element is an element that is complete by itself; it never contains other elements. Rather than being composed of a start tag, data, and an end tag, the empty element is a combined start and end tag.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With