从 Delphi 中的 IXMLDOMDOCUMENT 中删除空 <ul> 节点

Remove empty <ul> nodes from IXMLDOMDOCUMENT in Delphi

我在一个 xml 文档中有很多 xml 个节点。我想删除所有空的 <ul> 节点。我怎样才能做到这一点?

这是一个片段:

  <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>

我需要删除 <ul id="subject21"/>

您可以使用简单的递归。这是一个示例:

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;

并且只传递文档根元素:

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;

编辑 递归函数 删除没有子节点但包含值的节点。例如:

<ul>
  blabla
</ul>

如果您想要相反的结果,您应该再添加一项检查 - 即:

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

或者这样 -