Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   .NET-Framework (managed code) (https://www.delphipraxis.net/79-net-framework-managed-code/)
-   -   Delphi XML Einstieg - wie? einfach? Stringgrid ins XML und zurück! (https://www.delphipraxis.net/170896-xml-einstieg-wie-einfach-stringgrid-ins-xml-und-zurueck.html)

matashen 9. Okt 2012 09:02

XML Einstieg - wie? einfach? Stringgrid ins XML und zurück!
 
Hallo zusammen,

möchte jetzt langsam mal ins XML einsteigen.

Hab auch schon einiges dazu im Web gesucht und auch gefunden.

Meistens geht es aber in den gefundenen Tutorials ums einladen und manipulieren von bestehenden XML Strukturen, Serialisieren von Objekten in XML - auch interessant.
Aber die Basics zum erstellen eigener XML Datensätze befassen sich dann nur mit der wohlgeformtheit von XML Dokumenten oder die Verwendung einfacher zusatzKomponenten was aber dann nicht mehr macht als ich auch mit ini machen kann. Was ich aber nicht finde wie ich mit einfachen Boardmitteln ein XML Dokument erstellen und füttern kann.
Ich habe Delphi XE2 und da gibt es ja das schöne XMLDocument.

Zum Start dachte ich ich fütter einfach mal ein Dokument mit dem Inhalt einer Stringgrid und les das wieder zurück. Nur fehlt wir der Ansatz.

Hat jemand ein kleines Beispielprogramm oder ne kurze erklärung wie ich das mache?

Und bitte nicht auf Suche verweisen ich google und forensuche schon seit 2 Stunden und komplizierte Behandlungen zu dem Thema gibt es ganz viele. Aber so ein simpler Anfang den ich machen möchte findet man(ich) nicht - ausser wieder verweise auf andere verweise die ich als unbrauchbar einstufe oder in einer loop wieder auf den ersten Verweis landen.

Gruß Matthias

himitsu 9. Okt 2012 09:19

AW: XML Einstieg - wie? einfach? Stringgrid ins XML und zurück!
 
Schau mal in mein Hier im Forum suchenhimXML rein.
Dort gibt es einen Ordner mit Testprojekten, und in Einem davon (dem Vergleichs-Projekt) wird, unter Anderem, auch dein XMLDocument MSXML-DOM verwendet

Tipp: Du solltest dir auch überlegen, ob du TXMLDocument oder IXMLDocument verwendest, denn die Verwaltung der Speicherreferenzen ist da etwas unterschiedlich.
Delphi-Quellcode:
var
  C: TXMLDocument;
  I: IXMLDocument;

// als Objekt-Instanz erstellen und so verwalten
C := TXMLDocument.Create;
...
C.Free;

// zwar als Objekt-Instanz erstellen, aber dann direkt als Interface nutzt
// erstellt intern die neuste MSXML-Version, welche es kennt und die es im System findet
I := TXMLDocument.Create;
...
//I := nil;

// direkt als Interface erstellen und nutzt (so kann man genau entscheiden welche MSXML-Version man nutzen will)
I := CoCreateObject...; // oder irgendwie so ... vergeß ich ständig, steht aber bestimmt in vielen Tutorials drin
...
//I := nil;

Es gibt grundsätzlich 2 Wege, welche Viele zum Erstellen eines leeren Dokuments nutzen.

- Man läd ganz einfach ein "leeres" Dokument rein.
XML-Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><xmlroot></xmlroot>

Meist gibt es ja sowas wie eine "LoadFromXML"-Funktion, wo man die Datei als String laden kann.

- Oder man erstellt eine XML-Instanz, erzeugt den RootKnoten (was bei einigen XML-Libs manchml automatisch geht) und setzt eventuell noch ein paar Optionen, so wie z.B. die XML-Version, das Encoding und ob Standalone.

p80286 9. Okt 2012 09:59

AW: XML Einstieg - wie? einfach? Stringgrid ins XML und zurück!
 
Endlich mal einer, der den ersten Schritt auch mal benennt!!
:thumb:

Gruß
K-H

matashen 9. Okt 2012 11:13

AW: XML Einstieg - wie? einfach? Stringgrid ins XML und zurück!
 
Hallo,

erstmal danke für die Antwort

Zitat:

- Man läd ganz einfach ein "leeres" Dokument rein.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><xmlroot></xmlroot>
Meist gibt es ja sowas wie eine "LoadFromXML"-Funktion, wo man die Datei als String laden kann.
Das ist genau der Ansatz der vermutlich einfacher ist als den root Knoten zu erzeugen.

Ich hab auch in den Methoden von XMLDocument keinen aufruf zum erstellen des root knotens gefunden.
Daher ist mir unklar ob der automatisch erzeugt wird, oder ob man in durch createnode selbst erzeugen muss.

Delphi-Quellcode:
var
  C: TXMLDocument;
  I: TXMLDocument;

// als Objekt-Instanz erstellen und so verwalten
C := TXMLDocument.Create;
...
C.Free;

// zwar als Objekt-Instanz erstellen, aber dann direkt als Interface nutzt
// erstellt intern die neuste MSXML-Version, welche es kennt und die es im System findet
I := TXMLDocument.Create;
sorry aber den unterschied check ich nicht. c und i sind doch identisch aufgerufen :-/

Gruß Matthias

Bummi 9. Okt 2012 11:31

AW: XML Einstieg - wie? einfach? Stringgrid ins XML und zurück!
 
war ein Tippfehler von himi ....
Delphi-Quellcode:
procedure TForm3.Button1Click(Sender: TObject);
var
  C: TXMLDocument;
  I: IXMLDocument;
  Node: IXMLNode;
begin
  {
  C := TXMLDocument.Create(nil); // >> Memoryleaks wenn  C.Free; am Ende fehlt
  C.Active := True;

  C.DocumentElement := C.CreateNode('Hauptelement', ntElement, '');
  C.DocumentElement.Attributes['attrName'] := 'Attribut';
  Node := C.DocumentElement.AddChild('Ein_Kind', -1);
  Node.Text := 'Mit diesem Inhalt';
  Node := Node.AddChild('Ein_KindesKind', -1);
  Node.Text := 'Mit KindesKind Inhalt';

  C.SaveToFile('C:\temp\test.xml');
//  C.Free; //>> just 4 fun
  }

  I := TXMLDocument.Create(nil);  // keine Memoryleaks
  I.Active := True;

  I.DocumentElement := i.CreateNode('Hauptelement', ntElement, '');
  I.DocumentElement.Attributes['attrName'] := 'Attribut';
  Node := i.DocumentElement.AddChild('Ein_Kind', -1);
  Node.Text := 'Mit diesem Inhalt';
  Node := Node.AddChild('Ein_KindesKind', -1);
  Node.Text := 'Mit KindesKind Inhalt';

  I.SaveToFile('C:\temp\test.xml');

end;

procedure TForm3.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutDown:=true;
end;

himitsu 9. Okt 2012 12:10

AW: XML Einstieg - wie? einfach? Stringgrid ins XML und zurück!
 
Das Erstellen ist eigentlich nicht so schwer.
Der Root-Knoten ist auch nur ein ganz normaler XmlNode, so wie alle anderen Unterknoten auch, nur daß er eben nicht als Child an einem Node hängt, sondern am Document.

Wie gesagt ... siehe meine Demoanwendung.
Dort werden ja auch Dokumente dynamisch neu erzeugt.

Aus der CheckLibs-Demo:
Delphi-Quellcode:
var
  XML: TXMLDocument;
  Root, Node: IXMLNode;
 
XML := TXMLDocument.Create(nil);
XML.Active := True;
//XML.Version := '1.0';
//XML.StandAlone := 'yes';
//XML.Encoding := 'UTF-8';
Root := XML.AddChild('xml');
//for i := 0 to 9999 do
//  Node := Root.AddChild('Node' + IntToStr(i));
XML.SaveToFile(ChangeFileExt(ParamStr(0), '.xml'));
XML.Free;
Also sind das auch nur 2 Zeilen (Active+AddChild), gegenüber der einen Zeile, um die XML als String zu laden.
Delphi-Quellcode:
var
  XML: IXMLDocument;
 
XML := TXMLDocument.Create(nil);
XML.Active := True;
XML.AddChild('xml');
XML.SaveToFile(ChangeFileExt(ParamStr(0), '.xml'));
Zitat:

Zitat von matashen (Beitrag 1186360)
sorry aber den unterschied check ich nicht. c und i sind doch identisch aufgerufen :-/

War'n Copy&Paste-Error :oops:
Der Unterschied sollten die Zielvariablen TXMLDocument/IXMLDocument sein. (notfalls hätte man sich das eventuell aus den Namen Component/Interface erraten können)

Bummi 9. Okt 2012 12:30

AW: XML Einstieg - wie? einfach? Stringgrid ins XML und zurück!
 
Es sind beliebig viele Arten der Implementierung möglich, eine der einfachsten dürfte das hier sein ...

Delphi-Quellcode:
Procedure SaveStringGrid2XML(sg:TStringGrid;const fn:String);
//2012 bummi
var
  C, r: Integer;
  row: IXMLNode;
  I: IXMLDocument;
begin
  I := TXMLDocument.Create(nil);
  I.Active := True;
  I.DocumentElement := I.CreateNode('DATA', ntElement, '');
  for r := 0 to sg.RowCount - 1 do
  begin
    row := I.DocumentElement.AddChild('ROW');
    for C := 0 to sg.ColCount - 1 do
    begin
      row.Attributes['COL'+IntToStr(C)] := sg.Cells[c,r];
    end;
  end;
  I.SaveToFile(fn)
end;



Procedure LoadStringGridFromXML(sg:TStringGrid;Const fn:String);
//2012 bummi
var
  I: IXMLDocument;
  row: IXMLNode;
  r,c:Integer;
  Procedure SetColCount;
    begin
       if sg.ColCount<>row.AttributeNodes.Count then sg.ColCount := row.AttributeNodes.Count;
    end;
begin
  I := TXMLDocument.Create(fn);
  I.Active := true;
  I.DocumentElement := i.ChildNodes[0];
  sg.RowCount := I.DocumentElement.ChildNodes.Count;
  for r := 0 to I.DocumentElement.ChildNodes.Count-1 do
    begin
       row := I.DocumentElement.ChildNodes[r];
       if r=0 then SetColCount;
       for c := 0 to row.AttributeNodes.Count - 1 do
          begin
            //sg.Cells[c,r] := row.Attributes['COL'+IntToStr(C)];
            sg.Cells[c,r] := row.AttributeNodes.Get(c).Text;
          end;
    end;
end;

matashen 9. Okt 2012 12:44

AW: XML Einstieg - wie? einfach? Stringgrid ins XML und zurück!
 
Danke Jungs,

langsam wird mir der Start des ganzen verständlich.
Das heist wenn ich mir das Beispiel von Bummi ansehe, der root-node wird bei create vermutlich automatsich erzeugt - aber das test ich mal.

Basis zum testen hab ich jetzt ja.


Gruß Matthias

himitsu 9. Okt 2012 12:54

AW: XML Einstieg - wie? einfach? Stringgrid ins XML und zurück!
 
Zitat:

Zitat von matashen (Beitrag 1186374)
Das heist wenn ich mir das Beispiel von Bummi ansehe, der root-node wird bei create vermutlich automatsich erzeugt

Zitat:

Delphi-Quellcode:
I.DocumentElement := I.CreateNode('DATA', ntElement, '');

Er wird erst danach erzeugt und dann scheinbar etwas "anders" zugewiesen.

Das MS-XML-DOM kennt auch die Option AutoCreateNode.
Da werden Nodes automatisch erzeugt, wenn man drauf zugreifen will und diese existieren noch nicht.

Das kann aber auch Probleme bereiten, denn wenn man sich z.B. verschreibt, einen Knoten und dessen Unterknoten auslesen will und dann auf was Falsches zugreift, dann wundert man sich schon etwas, warum es darin keine Unterknoten mehr gibt.


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