Reputation: 13
I am looking to remove empty xml tags which are under a particular tag.
For Example, I have this XML:
<?xml version="1.0" encoding="UTF-16"?>
<apiRequest>
<policyTransaction>
<addDriver>
<driverName>xyz</driverName>
<IsCoInsured/>
<OnlyInsuredWithThisPolicy/>
</addDriver>
<retrieveDrivers/>
<validateDrivers/>
</policTransaction>
</apirequest>
I want this to be:
<?xml version="1.0" encoding="UTF-16"?>
<apiRequest>
<policyTransaction>
<addDriver>
<driverName>xyz</driverName>
</addDriver>
<retrieveDrivers/>
<validateDrivers/>
</policTransaction>
</apirequest>
I am using the code below to do this
var doc= XDocument.Parse(requestString);
var emptyElements = from descendant in doc.Descendants()
where descendant.IsEmpty || string.IsNullOrWhiteSpace(descendant.Value)
select descendant;
emptyElements.Remove();
But the elements after the adddriver also get eliminated.
<?xml version="1.0" encoding="UTF-16"?>
<apiRequest>
<policyTransaction>
<addDriver>
<driverName>xyz</driverName>
</addDriver>
</policTransaction>
</apirequest>
Which I don't want to happen. How could I check only for child elements to be removed if they are empty? I want the elements retrieveDrivers and validateDrivers to be there.
The above is obtained by a request, so once this XML is sent I get the response back with the elements for those two tags filled.
Upvotes: 0
Views: 2306
Reputation: 13
It is working fine If I use it in this way.
var requestString = XmlSerializer.Serialize(request);
var requestStringWithoutNullElements = XDocument.Parse(requestString);
var emptyElements = from descendant in requestStringWithoutNullElements.Descendants()
where descendant.IsEmpty && descendant.Name != "retrieveDrivers" && descendant.Name != "validateDrivers"
select descendant;
emptyElements.Remove();
Upvotes: 0
Reputation: 9467
You want to only remove empty elements from a specific element, not the document in general, so instead of
doc.Decendants()
use
doc.Descendants("addDriver").Elements() // all sub elements of elements called addDriver
This is the most simple solution. This doesnt remove elements that had only empty elements.
Be careful though, if there are namespaces declared, you have to use the correct XName instead of plain string. See this for more info.
Here is a more generic approach using System; using System.Linq; using System.Xml.Linq;
namespace Sandbox { public class Program {
public static void Main(string[] args)
{
string xml = @"<?xml version='1.0' encoding='UTF-16'?>
<apiRequest>
<policyTransaction>
<addDriver>
<driverName>xyz</driverName>
<IsCoInsured/>
<OnlyInsuredWithThisPolicy/>
</addDriver>
<retrieveDrivers/>
<validateDrivers/>
</policyTransaction>
</apiRequest>";
XDocument doc = XDocument.Parse(xml);
doc.Root.RemoveEmptyChildren("addDriver");
Console.WriteLine(doc);
Console.ReadKey();
}
}
public static class XElementExtension
{
public static void RemoveEmptyChildren(this XElement element, XName name = null, bool recursive = false)
{
var children = name != null ? element.Descendants(name) : element.Descendants();
foreach (var child in children.SelectMany(child => child.Elements()).ToArray())
{
if (child.IsEmpty || string.IsNullOrWhiteSpace(child.Value))
child.Remove();
}
}
}
}
Upvotes: 1