1

I have many xml nodes in an xmldocument. I want to remove all the empty <ul> nodes. How can I accomplish this?

Here is a snippet:

  <li>
    <a href="javascript:void(0);">Level 1</a>
    <ul id="subject19">
      <li>
        <a href="javascript:void(0);">Level 2</a>
        <ul id="subject20">
          <li>
            <a href="javascript:void(0);">Level 3</a>
            <ul id="subject21"/>
          </li>
        </ul>
      </li>
    </ul>
  </li>

I need to remove <ul id="subject21"/>

3
  • Which XML library are you using? Commented May 14, 2015 at 8:59
  • Use RemoveChild on the parent node Commented May 14, 2015 at 9:23
  • I need to recursively loop through the structure, identify the empty nodes and remove. I'm not sure how to accomplish this. I am aware of RemoveChild. Commented May 14, 2015 at 9:36

1 Answer 1

2

You can use a simple recursion. Here is an example how:

procedure ScanAndRemove(aNode: IXMLNode);
var
  i: Integer;
  childNode: IXMLNode;
begin
  i := 0;
  while i < aNode.ChildNodes.Count do
  begin
    childNode := aNode.ChildNodes[i];
    if (childNode.NodeName = 'ul') and (childNode.ChildNodes.Count = 0) then
      aNode.ChildNodes.Remove(childNode) else
      begin
        ScanAndRemove(childNode);
        Inc(i);
      end;
  end;
end;

And just pass the document root element:

procedure Cleanup;
var
  xmlDoc: IXMLDocument;
begin
  xmlDoc := TXMLDocument.Create(nil);
  try
    xmlDoc.LoadFromXML('...');
    ScanAndRemove(xmlDoc.DocumentElement);
    // now xmlDoc contains the desired result
  finally
    xmlDoc := nil;
  end;
end;

EDIT The recursive function will remove a node without children, but containing a value. Eg:

<ul>
  blabla
</ul>

If you want the opposite, you should add one more check - ie:

if (childNode.NodeName = 'ul') and 
  (childNode.ChildNodes.Count = 0) and 
  (VarToStrDef(childNode.NodeValue, '') = '') then
  ... 

Or this way - https://stackoverflow.com/a/9673869/3962893

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.