Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi Wie vom IDOMNode ein IXMLNode bekommen? (https://www.delphipraxis.net/142622-wie-vom-idomnode-ein-ixmlnode-bekommen.html)

Boro 31. Okt 2009 11:44


Wie vom IDOMNode ein IXMLNode bekommen?
 
Hallo,
hilft mir jemand wie vom IDOMNode zum IXMLNode kommen?
Die einzige Moglichkeit die ich kenne um einen Knoten zu finden ist durch XPath, zum B.
fur xml Datei
  • <?xml version="1.0" encoding="windows-1250"?>
    <books>
    <book>
    <title>Delhi Unleashed</title>
    <author>Calvert</author>
    </book>
    <book>
    <title>Delphi in a Nutshell</title>
    <author>Lischner</author>
    </book>
    </books>
funkzioniert bei mir folgendes Code
Delphi-Quellcode:
  var xiDocument: IXMLDocument;
      diNodeSelect: IDOMNodeSelect;
      diNodeList: IDOMNodeList;
      diNode: IDOMNode;
begin
  xiDocument := LoadXMLDocument('sample.xml');
  diNodeSelect := xiDocument.DocumentElement.DOMNode as IDOMNodeSelect;
  diNode := diNodeSelect.selectNode('/books/book/title');
  diNodeList := diNodeSelect.selectNodes('/books/book/author');
Um XPath zu nutzen muss ich vom IXMLNode zu IDOMNodeSelect bzw. IDOMNode interface down cast machen. Gibt es die Moglichkeit die gefundene Knoten vom IDOMNode zuruck zum IXMLNode bringen? Oder muss ich dann weiter nur IDOMNode interface verwenden, um mit den gefundenen Knoten weiter zu arbeiten?

MarcoWarm 4. Nov 2009 11:29

Re: Wie vom IDOMNode ein IXMLNode bekommen?
 
Hi,

so sollte es gehen:
Delphi-Quellcode:
//achte auf uses msxml
var Document: IXMLDOMDocument;
    NodeList: IXMLDOMNodeList;
    Node: IXMLDOMNode;
begin
  Document:=CoDOMDocument.Create;
  Document.load('sample.xml');
  Node := Document.DocumentElement.selectSingleNode('/books/book/title');
  NodeList := Document.DocumentElement.selectNodes('/books/book/author');
end;
Gruß
Marco

Boro 4. Nov 2009 20:08

Re: Wie vom IDOMNode ein IXMLNode bekommen?
 
Danke Marco fur den Rat. Dein Vorschlag ist also IXMLDOMNode anstatt IXMLNode. Aus dem Beispiel sehe ich, das IXMLDOMNode auch die Suche mit XPath (selectNodes) ermoglicht und die Suche gibt zuruck wieder IXMLDOMNode. Das finde ich besser als beim IXMLNode, wo ich wegen der Suche zum IDOMNode wechseln muss und es gibt kein Weg zuruck. Deswegen wollte ich an IXMLNode verzichten (leider auch an Binding Wizard) und nur dem IDOMNode benutzen. Deine Antwort zeigt das neben IDOMNode auch IXMLDOMNode die Suchmoglichkeit hat ohne den Knotentyp wechseln zu mussen.
Der IXMLDOMNode hat aber leider Nachteil - ich finde gar nichts uber ihm in der Hilfe im Delphi 2006. Alles nur aus den msxml.pas rauszufinden geht zu langsam bei mir.
Ich fuehle mich verloren bei den Typen IXMLNode, IDOMNode, IXMLDOMNode. Ich kenne nicht den Zusammenhang zwischen ihnen. In der Delphi Hilfe steht, das IXMLNode einfacher sein soll als IDOMNode. Ich weiss nicht wie dazu der IXMLDOMNode passt. Dazu noch msxml.pas und xmlinf.pas beide definieren IXMLDocument und konnen nicht gleichzeitig benutzt werden. Sind die beiden entweder oder?
Sollte mann mit msxml.pas auch selbst den Import aus der aktuellen Type Library msxml?.dll machen ?

Boro 6. Nov 2009 23:02

Re: Wie vom IDOMNode ein IXMLNode bekommen?
 
Vieleicht hab ich die Antwort gefunden in einem prachtvollem Stück Code vom Midiar geschrieben für OpenXML. Der hat Funktionen SelectNode and SelecNodes mit Parameter IXMLNode Knoten und XPath string, die den IXMLNode bzw. IXMLNodeList zurück geben. Die schaffen es mittels Aufruf des TXMLNode.Create mit gefundenen IDOMNode Knoten als Parameter.
Das ist es was ich wollte - mit IXMLNode und IXMLDocument anfangen, mittels XPath die gewunschte Knoten finden und weiter mit ihnen als IXMLNode arbeiten.
Ich hab's ausprobiert und es funkzioniert. Ich hoffe das es wirklich so geht. Kann es jemand bestätigen?

aegidos 21. Mär 2010 07:28

Re: Wie vom IDOMNode ein IXMLNode bekommen?
 
Hallo,
ich habe hier auch ganz speziell eine Frage zur IXMLNode Schnittstelle und IXMLDOMNodeList.

Um an ein XML File Knoten anzuhängen bzw. falls die Knoten schon bestehen sollten nur die Werte (also das Text Attribut) neu zu setzen habe ich unten stehende Procedure geschrieben.

Bei der Verwendung von XPath zeigt sich hier eine seltsame Eigenheit.
Verwende ich ein hart codiertes XPath Statement so wird der Knoten in der Quelldatei gefunden.
Wenn ich das Traversieren abhängig von einer Variablen mache hört der Spass schon auf und der Knoten wird nicht gefunden. Woran kann das denn liegen?

QUELLDATEI
Delphi-Quellcode:
<dates>
   <data>sthlike input1</data>
   <data cname="dummy">sthlike input2</data>
   <data cname="0">sthlike input3</data>
</dates>
Die Procedure
Delphi-Quellcode:
procedure TForm1.ParseMSXML(const FileName: TFileName);
var Document: IXMLDOMDocument;
    NodeList: IXMLDOMNodeList;
    Node: IXMLDOMNode;
    xmlTag: string;
    i,k: Integer;
begin
  if FileExists(FileName)then
  begin
  Document:=CoDOMDocument.Create;
  Document.load(FileName);

      // loop through cells -- Hashtabelle mit korrespondierenden Wertepaaren
    for i := 0 to LogDlg.dataGrid.RowCount - 1 do
      for k := 0 to LogDlg.dataGrid.ColCount - 1 do
      begin
        if (LogDlg.dataGrid.Cells[k, i] <> '')and (LogDlg.dataGrid.Cells[k+1, i] <> '') then
        begin
        //in xmlTag steht der Wert den das Attribut cname dann bekommen soll
           xmlTag := StringReplace(LogDlg.dataGrid.Cells[k, i], ' ', '', [rfReplaceAll, rfIgnoreCase]);
         // Knoten mit XPath selektieren
//Hier wird nach cname="0" gesucht aber kein Knoten gefunden obwohl in xmlTag eindeutig '0' steht
//gibts hier ein Problem bei der Verwendung von Variablen in XPath Statements?
//muss ich meinen String noch irgendwie casten oder machen die ANführungszeichen Ticks Probleme?
          Node := Document.DocumentElement.selectSingleNode('/dates/data[@cname="xmlTag"]');
          if(node<>nil)then begin
                Node.Text:=LogDlg.dataGrid.Cells[k+1, i];

          end else begin
//Hier wird nach cname="0" gesucht und auch ein Knoten gefunden !!
              Node := Document.DocumentElement.selectSingleNode('/dates/data[@cname="0"]');
              Node.Text:=LogDlg.dataGrid.Cells[k+1, i];
          end;

        end;

      end;


  Document.save(FileName);
  end;
end;
Vielen Dank schon vorab !
Grüße
Andreas

aegidos 22. Mär 2010 07:17

Re: Wie vom IDOMNode ein IXMLNode bekommen?
 
Sorry für Doppelpost,
Aber habe das Problem gefunden.

Nun benutze ich einen string, den ich der SelecNodes mitgebe:

Delphi-Quellcode:
strXPath :=    '/datagrid/data[@cname="' +xmlTag+'"]';
Dann klappt's auch :-D

Danke dennoch,
Grüße
Andreas


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:41 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz