Delphi IXMLDocument删除XPath结果节点

时间:2018-05-22 16:47:04

标签: xml delphi xpath

我使用xpath搜索某些节点,并希望从文档中删除这些节点。有办法吗? 问题是delphi中的xpath导致IDOMNode而不是IXMLNode。 我可以获得“原始”IXMLNode吗? 代码基本上是这样的 - 在IXMLNode N中搜索,使用Expr for xpath。

var
  XPathDOMNodeList: IDOMNodeList;
  DN : IDomNode;

begin  
  if Assigned(N) and
     Supports(N.DOMNode, IDOMNodeSelect, DOMNodeSelect) then
  begin
    XPathDOMNodeList := DOMNodeSelect.selectNodes( Expr );
    if Assigned( XPathDOMNodeList ) and ( XPathDOMNodeList.length > 0 ) then
    begin
      DN := _XPathDOMNodeList.item[ 0 ];

      // now how to remove original IXMLNode matching DN ???    

    end;
  end;
...

1 个答案:

答案 0 :(得分:0)

我终于这样做了:首先使用在某处找到的方法将IDOMNode转换为IXMLNode,然后为此设置随机属性,以便可以遍历doc进行搜索。它至少适用于Element节点,这就是我所需要的。 我并不完全理解第一个转换步骤的工作原理,但确实如此。

function xmlDomNodeToXMLNode( N : IDOMNode ):IXMLNode; overload;
var
  intfDocAccess : IXmlDocumentAccess;
  doc: TXMLDocument;
begin
  if N = NIL then
    Result := NIL
  else begin
    if Supports( N.OwnerDocument, IXmlDocumentAccess, intfDocAccess) then
      doc := intfDocAccess.DocumentObject
    else
      doc := _xpathdoc as TXMLDocument; // _xpathdoc was used before for XPath query
    Result := TXmlNode.Create( N, nil, doc );
  end;
end;


var
  _an,_av : string;

function xmlDOMNodeToXMLNode( D : IXMLDocument; DN : IDOMNode ):IXMLNode; overload;
  function GetIt2( N : IXMLNode ):IXMLNode;
  var
    i : integer;
  begin
    if N.HasAttribute( _an ) and ( N.GetAttribute( _an ) = _av ) then
      Result := N
    else begin
      for i := 0 to N.ChildNodes.Count-1 do
      begin
        Result := GetIt2( N.ChildNodes[i] );
        if Assigned( Result ) then
          Exit;
      end;
    end;
  end;

var
  N : IXMLNode;
  i : integer;
begin
  N := xmlDomNodeToXMLNode( DN );
  _an := Format( 'a%d', [ random(1000000) ] );
  _av := Format( 'v%d', [ random(1000000) ] );
  N.SetAttribute( _an, _av );

  Result := GetIt2( D.DocumentElement );

  for i := 0 to N.AttributeNodes.Count-1 do
    if N.AttributeNodes[i].NodeName = _an then
    begin
      N.AttributeNodes.Remove( N.AttributeNodes[i] );
      break;
    end;
end;


....

  XMLNode := xmlDOMNodeToXMLNode( Doc, DOMNode );
  XMLNode.ParentNode.ChildNodes.Remove( XMLNode );