views:

179

answers:

2

I'm doing some transforms using xlinq and some of those transforms can result in leaving empty elements in the document.

Once I am done all of those transforms, how can I query an xdocument for all empty elements?

In other words; if I remove all <a> tags which happen to be the only element inside an <li> tag, how do I remove the empty <li>?

Before:

XDocument.Parse(@"<body>
   <ul><li><a href="#">Joy</a></li></ul>
   <p>Hi.</p>
</body>").Descendants("a").Remove();

After:

<body>
   <ul><li/></ul>
   <p>Hi.</p>
</body>

I would prefer:

<body>
   <p>Hi.</p>
</body>
A: 

The best I could come up with was...

var emptyElements = 
    from element in document.Descendants()
    where !element.Attributes().Any() && !element.Elements().Any()
    select element;


while(emptyElements.Any())
    emptyElements.Remove();

Then I realized that was a bad idea, it was removing too much but I didn't take the time to figure out why.

Dave
+1  A: 

Checking if element doesn't have attributes and doesn't have elements is not enough. You need to check if an element is truly empty (absolutely no content). XElement has a property, that actually helps you do that - XElement.IsEmpty.

var document = XDocument.Parse(@"<body><ul><li><a href='#'>Joy</a></li></ul><p>Hi.</p></body>");
document.Descendants("a").Remove();

var emptyElements = from element in document.Descendants()
                    where element.IsEmpty
                    select element;

while (emptyElements.Any())
    emptyElements.Remove();
Mindaugas Mozūras