Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi XML-Node von einem XML-Document in ein anderes verschieben (https://www.delphipraxis.net/53715-xml-node-von-einem-xml-document-ein-anderes-verschieben.html)

alzaimar 21. Sep 2005 19:20


XML-Node von einem XML-Document in ein anderes verschieben
 
Hallo,

Ich habe hier ein IXMLDocument A mit einigen Nodes A.Nodes[]. Nun will ich einen Knoten in ein zweites IXMLDocument B verschieben, das die gleiche Datenstruktur beinhaltet, schematechnisch also kein Problem.

Nur, wie geht das? Ich bräuchte sowas wie:
Delphi-Quellcode:
Procedure TransferNode (aSrcDoc, aDestDoc : IXMLDocument; aNodeIndex : Integer);
Begin
  ...
End;
Sei A eine Liste von Nodes [N0,N1,N2] und B eine Liste [M0,M1]. Dann soll der Aufruf TransferNode (A,B,2) Folgendes liefern: A=[N0,N1] und B=[M0,M1,N2].

Das kann doch nicht so schwer sein. Natürlich könnte ich umständlich einen leeren Knoten in B erzeugen und dann einzeln (und rekursiv) alle Attribute und Unterknoten kopieren, und dann anschliessend den Knoten löschen, aber das ist doch krank.

Kann mir da Einer helfen?

Danke

marabu 21. Sep 2005 20:52

Re: XML-Node von einem XML-Document in ein anderes verschieb
 
Hi alzaimar,

hast du MS Office 2003 installiert? Dann hast du MSXML5 und kannst (endlich) mit importNode() arbeiten - Methode von IXMLDOMDocument3. Wenn du nur MSXML4 hast, dann musst du mit IXMLDOMDocumentFragment arbeiten. Code kann ich dir erst morgen geben.

Grüße vom marabu

alzaimar 21. Sep 2005 20:59

Re: XML-Node von einem XML-Document in ein anderes verschieb
 
Hi marabu!

Danke für die Antwort: Beim Kunden steht bestimmt kein OFS 2003 rum... IXMLDOMDocumentFragment? Ich schau mal nach. Danke für die Mühe.

Ach, und Code wäre nett. Kann ja sein, das die Senilität wieder zuschlägt!

Bis denne

Als Eimer

marabu 21. Sep 2005 21:15

Re: XML-Node von einem XML-Document in ein anderes verschieb
 
Was du heute kannst besorgen...

Ohne MSXML5:

Delphi-Quellcode:
procedure TransferNode(nParentSrc, nParentDst: IXMLDOMNode; index: integer);
var
  n: IXMLDOMNode;
begin
  n := nParentSrc.childNodes.item[index];
  nParentDst.appendChild(nParentSrc.removeChild(n));
end;
[edit] Oder einfach:

Delphi-Quellcode:
procedure TransferNode(nParentSrc, nParentDst: IXMLDOMNode; index: integer);
begin
  nParentDst.appendChild(nParentSrc.childNodes.item[index]);
end;
Das geht zur Not schon ohne procedure...[/edit]

marabu

GuenterS 21. Sep 2005 21:57

Re: XML-Node von einem XML-Document in ein anderes verschieb
 
Ist die Installation von Office 2003 eigentlich die einzige Möglichkeit um an MSXML5 zu kommen?

marabu 22. Sep 2005 06:03

Re: XML-Node von einem XML-Document in ein anderes verschieb
 
Hi Günter,

im Prinzip: JA.

Grüße vom marabu

GuenterS 22. Sep 2005 08:09

Re: XML-Node von einem XML-Document in ein anderes verschieb
 
Das ist schade, denn MSXML4 hat man ja auch so bekommen ohne office.

alzaimar 22. Sep 2005 09:29

Re: XML-Node von einem XML-Document in ein anderes verschieb
 
Leider klappt das bei mir irgendwie nicht, weil ich den Typen IXMLDOMNode nicht finde, sondern nur IDOMNode. Damit passier aber - gar nix!
Ich musste mir so behelfen
Delphi-Quellcode:
Function MoveNode (aSrc, aDest : IXMLNodeCollection; aIndex : Integer) : IXMLNode;
Var
  n : IXMLNode;
  i : Integer;

Begin
  n := aSrc.Nodes [aIndex];
  i := adest.ChildNodes.Add (n.CloneNode(True));
  aSrc.Remove(n);
  Result := aDest.Nodes [i];
End;
Das ist zwar ein Overhead, weil der Knoten erst dupliziert wird, aber als Notlösung immer noch besser als rekursives Kopieren. So langsam hab ich kein' Bock mehr, mit MSXML zu arbeiten. Mein Mitstreiter verwendet Java und schmunzelt immer über meine Wutanfälle...

marabu 22. Sep 2005 09:46

Re: XML-Node von einem XML-Document in ein anderes verschieb
 
Hi alzaimar,

für nächstes Mal: mach ein Konsolfenster auf, geh in deinen Delphi Imports Ordner und starte TLIBIMP:

Code:
tlibimp -Fe- %windir%\system32\msxml4.dll
Dann kannst du die unit MSXML2.PAS als Komponente installieren. Wenn du die unit MSXML2 in deinen Programmen einbindest, dann stehen dir alle Interfaces zur Verfügung - und deinem Kollegen vergeht das Lachen.

[edit]
Eventuell hätte - ohne die Unit MSXML2 - auch das hier funktioniert:

Delphi-Quellcode:
procedure TransferNode(nSrc, nDst: IXMLNode; index: integer);
begin
  nDst.DOMNode.appendChild(nSrc.DOMNode.childNodes.item[index]);
end;
[/edit]

Grüße vom marabu

hboy 31. Mai 2011 22:16

AW: XML-Node von einem XML-Document in ein anderes verschieben
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Eventuell hätte - ohne die Unit MSXML2 - auch das hier funktioniert:
siehe Anhang. :(


und die IXMLNodeCollection-Geschichte funktioniert hier nicht, weil (iXMLNode-Instanz).Collection nil ist oO


ps. ich brauchte einen Export von payload, den ich zwar mit den restlichen Daten importiere, jedoch nicht direkt verwende, aber wieder speichern muss. Damit ich keine TXMLDocument-Instanzen herumschleppen muss, habe ich das Beiwerk als String abgelegt. So bekommt man die mit .XML ausgegebenen strings wieder importiert:

Delphi-Quellcode:
procedure StringToXMLNodes(parent: iXMLNode; str: String);
  var
    dummydoc   : TXMLDocument;
    dummysource : TStringStream;
    buffer     : String;
    primary    : iXMLNode;
    OneNode    : iXMLNode;
    idx        : integer;
begin
    if str = '' then exit;

    // wrap content into dummy document
    buffer := '<?xml version="1.0"?>'#13#10'<sheet>'+str+'</sheet>';
    dummysource := TStringStream.Create(buffer);
    dummysource.Seek(0,soFromBeginning);

    // use import functionality from this instance
    dummydoc := TXMLDocument.Create(Application);
    dummydoc.LoadFromStream(dummysource); // feed the instance
    dummydoc.Active := True;             // and activate it

    primary := dummydoc.Node.ChildNodes[1];   // just [1]: <sheet>...</sheet>

    if assigned(primary) then
    begin
      // clone nodes, insert
      for idx := 0 to primary.ChildNodes.Count -1 do
      begin
        OneNode := primary.ChildNodes[idx].CloneNode(true);
        parent.ChildNodes.Insert(-1,OneNode);
      end;
    end;

    // clean up
    dummydoc.Active := False;
    dummydoc.Destroy; // not sure if this is valid (what does Active=False do?)

    dummysource.Destroy;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:26 Uhr.

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