Einzelnen Beitrag anzeigen

Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: XPathQuery über IXMLNode

  Alt 19. Nov 2013, 11:15
In XSL bin ich nicht fit genug, um überhaupt auf die Idee zu kommen. Nett.

Ich habe bislang praktisch 1:1 die Lösung vom guten Zarko Gajic übernommen.


Delphi-Quellcode:
unit XpathHelper;

interface

   uses
      Xml.XMLIntf;


   type


      // Quelle: Zarko Gajic:
      // http://delphi.about.com/od/vclusing/qt/delphi-select-xml-nodes-ixmlnodelist-selectnodes-xpath-xmldom.htm, 18.06.2013
      // und
      // http://delphi.about.com/od/delphi-tips-2011/qt/select-single-node-ixmlnode-txmlnode-xpath-delphi-xmldom.htm, 18.06.2013

      /// <summary>
      /// Hilfsklasse, gibt <c>IXMLNode</c> bzw. <c>IXMLNodeList</c> für einen
      /// entsprechenden XPath zurück
        /// </summary>
      TXpathHelper = class

         class function SelectNode(xnRoot: IXmlNode; const nodePath: WideString): IXmlNode;
         class function SelectNodes(xnRoot: IXmlNode; const nodePath: WideString): IXMLNodeList;

      end;

implementation

   uses

      System.SysUtils,

      Xml.XMLDOM,
      Xml.XMLDoc
   ;



   class function TXPathHelper.SelectNodes(xnRoot: IXmlNode; const nodePath: WideString): IXMLNodeList;
    var
         intfSelect: IDomNodeSelect;
         intfAccess: IXmlNodeAccess;
         dnlResult: IDomNodeList;
         intfDocAccess: IXmlDocumentAccess;
         doc: TXmlDocument;
         i: Integer;
         dn: IDomNode;
   begin

      Result := nil;

      if not Assigned(xnRoot)
         or not Supports(xnRoot, IXmlNodeAccess, intfAccess)
         or not Supports(xnRoot.DOMNode, IDomNodeSelect, intfSelect)
      then
         Exit;

      dnlResult := intfSelect.SelectNodes(nodePath);
      if Assigned(dnlResult) then begin

         Result := TXmlNodeList.Create(intfAccess.GetNodeObject, '', nil);

         if Supports(xnRoot.OwnerDocument, IXmlDocumentAccess, intfDocAccess) then
            doc := intfDocAccess.DocumentObject
         else
            doc := nil;

         for i := 0 to dnlResult.length - 1 do begin
            dn := dnlResult.item[i];
            Result.Add(TXmlNode.Create(dn, nil, doc));
         end;
      end;
   end;

   class function TXPathHelper.SelectNode(xnRoot: IXmlNode; const nodePath: WideString): IXmlNode;
   var
      intfSelect : IDomNodeSelect;
      dnResult : IDomNode;
      intfDocAccess : IXmlDocumentAccess;
      doc: TXmlDocument;
   begin

      Result := nil;

      if
         not Assigned(xnRoot)
         or not Supports(xnRoot.DOMNode, IDomNodeSelect, intfSelect)
      then
         Exit;

      dnResult := intfSelect.selectNode(nodePath);

      if Assigned(dnResult) then begin
         if Supports(xnRoot.OwnerDocument, IXmlDocumentAccess, intfDocAccess) then
            doc := intfDocAccess.DocumentObject
         else
            doc := nil;

         Result := TXmlNode.Create(dnResult, nil, doc);
      end;

   end;

end.
Mehr habe ich bislang nie gebraucht. Im Endeffekt das selbe über IDomNodeSelect::selectNode(Str)
  Mit Zitat antworten Zitat