Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   XML fehlende Nodes automatisiert erstellen (https://www.delphipraxis.net/190380-xml-fehlende-nodes-automatisiert-erstellen.html)

matashen 29. Sep 2016 08:46

XML fehlende Nodes automatisiert erstellen
 
Hallo,

der Titel sagts schon,

ich soll eine bestehende Default.xml als neue Ziel.XML speichern und dabei einige Werte anpassen bzw. es fehlen Nodes die dann auch erzeugt werden müssen. Da das XML etwas größer ist wollte ich jetzt nicht jeden Knoten per Hand anlegen.

Zum auslesen verwende ich den TXPathhelper den ich hier im Forum bekommen habe, funktioniert soweit ganz gut.

Mein Problem: Wie erzeuge ich automatisch Nodes die in meiner bisherigen XML Struktur nicht existieren
Aufruf stell ich mir so vor

Delphi-Quellcode:
var neuerNode:IXmlNode;
.
.
neuerNode:=TXPathhelper.selectnode('/ersterNode/nocheiner/nasowas');
if neuerNode=Nil then neuernode:=TXPathHelper.CreateNodepath('/ersterNode/nocheiner/nasowas');
wie realisier ich sowas?

Der XPathhelper den ich benutze enthält folgenden Code
Delphi-Quellcode:
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;

Der schöne Günther 29. Sep 2016 09:31

AW: XML fehlende Nodes automatisiert erstellen
 
Eine
Delphi-Quellcode:
IXMLNode
hat die Methode
Delphi-Quellcode:
AddChild(..)
Beispiel:
Delphi-Quellcode:
procedure TForm17.Button1Click(Sender: TObject);
const
   nodePath = '/ersterNode/nocheiner/nasowas';
var
   asDoc:      IXMLDocument;
   asNode:      IXMLNode;
   newNode:   IXMLNode;
begin
   asDoc := LoadXMLData(Memo1.Text);
   asNode := TXpathHelper.SelectNode(asDoc.DocumentElement, nodePath);
   newNode := asNode.AddChild('neuerKnoten');
   newNode.Attributes['someAttribute'] := 'derp';

   Memo2.Text := asDoc.XML.Text;
end;
Memo1:
Code:
<ersterNode>
 <nocheiner>
  <nasowas />
 </nocheiner>
</ersterNode>
Memo2:
Code:
<ersterNode>
   <nocheiner>
      <nasowas><neuerKnoten someAttribute="derp"/></nasowas>
   </nocheiner>
</ersterNode>

matashen 29. Sep 2016 09:36

AW: XML fehlende Nodes automatisiert erstellen
 
Hi Günther,

das kenn ich selber - einen einzelnen Node hinzufügen,

ist aber nicht das worum ich gefragt habe ich hätte gernde die Erzeugung des gesamten paths aller Nodes die da enthalten sind. Und eben mit einem Befehl.

geht sowas?

Gruß Matthias

Der schöne Günther 29. Sep 2016 09:54

AW: XML fehlende Nodes automatisiert erstellen
 
Ach jetzt verstehe ich - Du möchtest mittels XPath eine Hierarchie anlegen. Also z.B. in einem komplett leeren XML mit einem Befehl einen Knoten mit der Adresse /ersterNode/nocheiner/nasowas erstellen sodass die Oberknoten mit erstellt werden?

Ich kenne da nichts vollautomatisches, vor allem nicht mit XPath (wie sollte das gehen?) Aber ist ja auch kein Hexenwerk in deinem speziellen Fall das selbst zu machen...

matashen 29. Sep 2016 12:19

AW: XML fehlende Nodes automatisiert erstellen
 
... und genau da häng ich grad mit meinem Gehirn fest.

Ich frag ja jetzt den vorhandenen Paramter mittels XPath ab,

das heist ich bekomm nil wenn der Knoten nicht existiert

dann möcht ich den erstellen, aber eben mit dem übergebenen String des XPath

Im prinzip sollte dann die Funktion so arbeiten


Function CreateNodepath(rootnode:IXMLNOde; nodepath:String):IXMLNode;
begin;
letzten Node extrahieren
dann mittels XPath prüfen ob parentNode existiert
wenn ja dann addchild(letzter Node)
wenn nein dann Createnodepath rekursiv aufrufen
neuen Node zurück geben
end;


so in etwa, aber wie ich das dann in Code Umsetze bekomm ich die Gehirnwindung nicht ganz zusammen. Vor allem wie zerlege ich den String des XPath um die Nodes dann zu erstellen. Gibts da passende Stringfunktionen die vom StringEnde bis gewähltes Zeichen einen String wegschneiden können?? Denn ich denke so in der art brauch ich was


hab jetzt mal versucht was zu schreiben, noch ungetestet ich wollte zuerst noch euch drüber gucken lassen

Delphi-Quellcode:
   class function TXPathhelper.CreateNode(xnRoot: IXMLNode; const nodepath: WideString):IXmlNode;
      var a,newpath,newchild:String;
          i:Integer;
          wantednode:IXMLNode;
    begin
       a:=nodepath;
       i:=length(a);
       while (a[i]<>'/') or (i>0) do dec(i);
       if i>0 then begin; //was gefunden dann extrahieren und XPath anwenden
        newpath:=copy(nodepath,1,i-1);
        newchild:=copy(nodepath,i+1,length(nodepath)-i);
        wantednode:=TXPathhelper.SelectNode(xnroot,newpath);
        if wantednode<>nil then begin;
                                xnroot.AddChild(newchild);
                                result:=TXPathhelper.SelectNode(xnroot,nodepath);
                            end
                           else result:=TXPathhelper.CreateNode(xnroot,newpath);

       end;
    end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:03 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