简体   繁体   中英

Delphi IXMLDocument remove XPath result node

I search for some nodes with xpath and want to remove these from the document. Is there a way to do it? The problem is that xpath in delphi results IDOMNode and not IXMLNode. Can I get the "original" IXMLNode back? The code is basically this - searching in IXMLNode N, using 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;
...

I finally made it this way: first convert the IDOMNode to IXMLNode with a method found somewhere, then set a random attribute for this so it can be searched with traversing the doc. It works for Element nodes at least, that's what I needed. I don't exactly understand how the first conversion step works, but it does.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM