Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#3

AW: XPathQuery über IXMLNode

  Alt 19. Nov 2013, 10:35
Im Prinzip wäre ein Link zu einem netten XPath-Tutorial nicht schlecht, oder notalls zur Wiki, aber zumindestens ein kleines Beispiel.
Nicht jeder kennt ja die Syntax oder weiß was XPath überhaupt ist.


Täuscht das, oder baust du die XML nach, nur halt mit den rausgefilterten Knoten und ihren Elternknoten?
Bzw. es wird alles entfernt, was nicht via XPath ausgewählt wurde oder ein Elternknoten eines ausgewählten knotens ist.

Wenn möglich solltest du niemals Interface-Instanzen und Object-Instanzen eines Objektes miteinander vermischen.
CreateWithParentNode sollte momit also IXMLNode als Result besitzen.

[edit] hab grade gemerkt, daß TXMLNode.Create das als Objekt haben will. (nur für TXMLNodeList.Add hätte ds aber gestimmt)

Und die Variable Document war doch eher nutzlos, da sie den Wert von OwnerDoc enthilt, womit man also gleich OwnerDoc verwenden kann.




Da, wo ich mal mit XPath rumgespielt hab, bin ich zwar direkt über IXMLDOMDocument und Co. gegangen, aber das sollte doch egal sein.
> siehe TLanguage im Hier im Forum suchenManifest-Creator

Zitat:
DomDoc2.setProperty('SelectionLanguage', 'XPath');
Ich wußte garnicht, daß man es vorher notfalls erst aktivieren muß?
Nja, zumindestens hat sich seit Jahren noch keiner beschwert, daß es nicht funktionierte, auch wenn ich es nicht erst aktiviert hatte.

An solchen Stellen, wo ein interface theoretisch eh immer unterstützt wird, da hab ich mir dieses Supports irgendwie abgewöhnt, vorallem wenn diese interfaces sowieso benötigt werden, damit die Funktion gewährleistet ist.
Aber ich weiß jetzt nicht mehr genau, seit welcher Delphiversion das geht.
XmlDocAccess := OwnerDoc.DOMDocument as IXMLDOMDocument2;
Notfalls wirft AS auch eine passende Exception.


Delphi-Quellcode:
function XPathQuery(aNode: IXMLNode; aQuery: string): IXMLNodeList; overload;
var
  XmlDocAccess: IXmlDocumentAccess;
  DomNodeList: IDomNodeList;
  i: integer;
  OwnerDoc: TXMLDocument;
  DomDoc2: IXMLDOMDocument2;

  function CreateWithParentNode(const aDomNode: IDOMNode; const aOwnerDoc: TXMLDocument): IXMLNode;
  begin
    if Assigned(aDomNode) then
      Result := TXMLNode.Create(aDomNode, CreateWithParentNode(aDomNode.parentNode, aOwnerDoc), aOwnerDoc)
    else
      Result := nil;
  end;

begin
  Result := nil;
  if not assigned(aNode) then
    Exit;
  if Supports(aNode.OwnerDocument, IXmlDocumentAccess, XmlDocAccess) then
    OwnerDoc := XmlDocAccess.DocumentObject
  else
    OwnerDoc := nil; // if Owner is nil this is a possble Memory Leak!

  // if XPath is not enabled
  if Assigned(OwnerDoc) and Supports(OwnerDoc.DOMDocument, IXMLDOMDocument2, DomDoc2) then
    DomDoc2.setProperty('SelectionLanguage', 'XPath');

  DomNodeList := (aNode.DOMNode as IDomNodeSelect).selectNodes(aQuery);
  if Assigned(DomNodeList) then
  begin
    Result := TXMLNodeList.Create((aNode as IXmlNodeAccess).GetNodeObject, '', nil);
    for i := 0 to Pred(DomNodeList.length) do
      Result.Add(CreateWithParentNode(DomNodeList.item[i], OwnerDoc));
  end;
end;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (19. Nov 2013 um 10:39 Uhr)
  Mit Zitat antworten Zitat