Fragen zu XML-Behandlung

Rund um die LCL und andere Komponenten
Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Fragen zu XML-Behandlung

Beitrag von Mathias »

Ich setze mich gerade mit XML-Dateien auseinander.
Ich habe es hingekriegt, das ich verschachtelte XML-Dateien auslesen kann.
Nur die Wurzelnode finde ich nicht, in meinem Fall <svg>
Der erste Eintrag, der gefunden wird, ist <title>.

Hat jemand eine Idee ?

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
const
  path = 'test.xml';
var
  doc: TXMLDocument;
  nodeList: TDOMNodeList;

  procedure Node(n: TDOMNodeList; schachtel: integer);
  var
    i: integer;
  begin
    for i := 0 to n.Count - 1 do begin
      Memo1.Lines.Add(StringOfChar(' ', schachtel * 4) + n.Item[i].NodeName);
      Node(n.Item[i].ChildNodes, schachtel + 1);
    end;
  end;

begin
  Memo1.Clear;
  ReadXMLFile(doc, path);

  nodeList := doc.DocumentElement.ChildNodes;  // Ich vermute, es liegt hier ?
  Node(nodeList, 0);

  doc.Free;
end;    
Die XML-Datei:

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="800.000" height="600.000" viewBox="0.0 0.0 800.000 600.000" version="1.1">
  <title>Produce by Acme CAD Converter</title>
  <desc>Produce by Acme CAD Converter</desc>
  <test1>
    <xmltest a="1" b="2" c="3"/>
    <xmltest>bla bla</xmltest>
    <xmltest>bla bla</xmltest>
    xmltest1 
    xmltest2 
  </test1>
  <test2 s="mein Test">
    <xmltest>bla bla</xmltest> 
    <xmltest>
    bla bla
    <br>
     hi hi
    </br>
    <xmltest>bla bla</xmltest>
    <xmltest>bla bla</xmltest>
    </xmltest>
  </test2>
  <polyline points="201.02,101.02 134.57,98.56" style="fill:none;stroke:black;stroke-width:0.5"/>
  <polyline points="134.57,137.59 201.02,135.13" style="fill:none;stroke:black;stroke-width:0.5"/>
</svg>
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Fragen zu XML-Behandlung

Beitrag von theo »

Wozu brauchst du den?

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Fragen zu XML-Behandlung

Beitrag von Mathias »

Erst mal kennen lernen, wie man mit XML Dateien arbeitet.

Und um evtl. später folgende Dateien auszulesen.
viewtopic.php?f=13&t=12954
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4888
Registriert: Fr 8. Apr 2011, 09:01

Re: Fragen zu XML-Behandlung

Beitrag von wp_xyz »

doc.DocumentElement IST der Root-Node.

Ich verwende statt der NodeList lieber die Funktionen für die Kinder (FirstChild) und Geschwister (NextSibling) der Nodes. Ich bilde mir ein, das wäre schneller, weil es direkt die Baumstruktur wiedergibt. So funktioniert auf jeden fall alles:

Code: Alles auswählen

uses
  laz2_dom, laz2_xmlread;
{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);

  procedure Node(ANode: TDOMNode; schachtel: integer);
  var
    i: integer;
    child: TDOMNode;
    nodeName: String;
    s: String;
  begin
    nodeName := ANode.NodeName;               // als separate Variablen für der Erleichterung der Arbeit mit dem Debugger.
    s := StringOfChar(' ', schachtel * 4) + NodeName;  // dt.
    Memo1.Lines.Add(s);
    child := ANode.FirstChild;
    while child <> nil do
    begin
      Node(child, schachtel + 1);
      child := child.NextSibling;
    end;
  end;

const
  path = 'test.xml';
var
  doc: TXMLDocument;
begin
  Memo1.clear;
  ReadXMLFile(doc, path);
  Node(doc.DocumentElement, 0);
  doc.Free;
end;
Im wiki-XML-Tuturial gibt es übrigens einen Abschnitt zur Anzeige einer XML-Datei in einer TreeView.

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Fragen zu XML-Behandlung

Beitrag von Mathias »

Sieht interessant aus, werde es bei Gelegenheit testen.

Danke.

Mit TreeView habe ich schon was gepastelt.
https://github.com/sechshelme/Lazarus-E ... r/test/XML
Das Wiki werde ich nochmals genauer angucken.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Fragen zu XML-Behandlung

Beitrag von Mathias »

Stimmt das, das es nur eine Wurzel geben darf ?

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<s123 xmlns="http://www.w3.org/2000/svg" width="800.000" height="600.000" viewBox="0.0 0.0 800.000 600.000" version="1.1">
  <desc>Produce by Acme CAD Converter</desc>
</s123>
<abc a="1" b="2" c="3">
  <polyline points="201.02,101.02 134.57,98.56" style="fill:none;stroke:black;stroke-width:0.5"/>
  <polyline points="134.57,137.59 201.02,135.13" style="fill:none;stroke:black;stroke-width:0.5"/>
</abc>
So eine XML scheitert schon be.i

Code: Alles auswählen

  ReadXMLFile(doc, path);
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Fragen zu XML-Behandlung

Beitrag von Socke »

Mathias hat geschrieben:
Di 26. Mai 2020, 15:00
Stimmt das, das es nur eine Wurzel geben darf ?
Im XML-Standard ist immer nur ein Wurzel-Element vorgesehen. Wenn du mehrere hast, ist das keine gültige XML-Datei mehr.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Fragen zu XML-Behandlung

Beitrag von Mathias »

Dann ist der Fall klar.

Danke
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Fragen zu XML-Behandlung

Beitrag von Mathias »

Ich verwende statt der NodeList lieber die Funktionen für die Kinder (FirstChild) und Geschwister (NextSibling) der Nodes. Ich bilde mir ein, das wäre schneller, weil es direkt die Baumstruktur wiedergibt. So funktioniert auf jeden fall alles:
Dies habe ich nun probiert:

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
var
  doc: TXMLDocument;

  procedure Node(ADOMNode: TDOMNode; ATreeNode: TTreeNode);
  var
    j: integer;
    child: TDOMNode;
    tree:TTreeNode;
  begin
    if ADOMNode.NodeName = '#text' then begin
      TreeView1.Items.AddChild(ATreeNode, ADOMNode.NodeValue);
    end else begin
      TreeView1.Items.AddChild(ATreeNode, ADOMNode.NodeName);
    end;

    if ADOMNode.HasAttributes then begin
      for j := 0 to ADOMNode.Attributes.Length - 1 do begin
        TreeView1.Items.AddChild(ATreeNode.GetLastChild, ADOMNode.Attributes.Item[j].NodeName +
          '= "' + ADOMNode.Attributes.Item[j].NodeValue + '"');
      end;
    end;

    child := ADOMNode.FirstChild;
    tree:=ATreeNode.GetLastChild;
    while child <> nil do begin
      Node(child, tree);
      child := child.NextSibling;
    end;

  end;

begin
  TreeView1.Items.Clear;
  ReadXMLFile(doc, path);
  TreeView1.Items.Add(nil, doc.DocumentElement.NodeName);
  Node(doc.DocumentElement, TreeView1.Items[0]);
  doc.Free;
  TreeView1.FullExpand;
end;
Nun habe ich das Problem, das die Wurzel 2 mal kommt.

Ich denke, das Problem liegt hier:

Code: Alles auswählen

  TreeView1.Items.Add(nil, doc.DocumentElement.NodeName);
  Node(doc.DocumentElement, TreeView1.Items[0]);
Die erste Zeile kann ich nicht weglassen, ansonsten geht Item[0] nicht.
Und bei Node, kann ich nicht nur "TreeView1 " mitgeben, da inkompatibel.
Dateianhänge
Bildschirmfoto vom 2020-05-28 16-42-46.png
Bildschirmfoto vom 2020-05-28 16-42-46.png (20.39 KiB) 2673 mal betrachtet
XML.zip
(131.41 KiB) 120-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Fragen zu XML-Behandlung

Beitrag von Mathias »

Gibt es bei den Attributes auch eine Lösung mit NextSibling ?

Momentan mache ich es mit einer Zählvariable.

Code: Alles auswählen

    if ADOMNode.HasAttributes then begin
      for j := 0 to ADOMNode.Attributes.Length - 1 do begin
        TreeView1.Items.AddChild(ATreeNode.GetLastChild,
          ADOMNode.Attributes.Item[j].NodeName + '= "' +
          ADOMNode.Attributes.Item[j].NodeValue + '"');
      end;
    end;   
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4888
Registriert: Fr 8. Apr 2011, 09:01

Re: Fragen zu XML-Behandlung

Beitrag von wp_xyz »

Mathias hat geschrieben:
Do 28. Mai 2020, 16:46
Nun habe ich das Problem, das die Wurzel 2 mal kommt.
Ich denke, das Problem liegt hier:

Code: Alles auswählen

  TreeView1.Items.Add(nil, doc.DocumentElement.NodeName);
  Node(doc.DocumentElement, TreeView1.Items[0]);
Die erste Zeile kann ich nicht weglassen, ansonsten geht Item[0] nicht.
Und bei Node, kann ich nicht nur "TreeView1 " mitgeben, da inkompatibel.
Wenn du Item[0] verwendest, dann hast du ja schon einen Node eingefügt. Nein, nimm einfach Nil als Argument im ersten Add()-Aufruf, dann wird der neue Node der Wurzel hinzugefügt.

Die Attribute sind keine Baumstruktur, daher gibt es nur den Array-artigen Zugriff.

Du kannst den Nodes auch Icons zuweisen. So kann man auf einen Blick unterscheiden, ob ein Node im TreeView einen Node der DOM-Struktur darstellt oder ein Attribut. Im beigefügten, abgeänderten Beispiel habe ich (im Button2-Click) einen kahlen Baum als Symbol für einen DOM-Node ohne Attribute, einen Baum mit Blättern als Symbol für einen DOM-Node mit Attributen, eine Liste als Symbol für ein Attribut und ein "T" für einen Text-Node genommen - ist etwas kindisch, dir fällt sicher etwas besseres ein.

Ach ja, der Add-Aufruf gibt den erzeugten Node als Funktionswert direkt zurück, das heißt, du musst den neuen Node nicht erst mit GetLastNode suchen.
Dateianhänge
xml-wp.zip
(5.57 KiB) 123-mal heruntergeladen
xml-tree.png
xml-tree.png (14.49 KiB) 2597 mal betrachtet

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Fragen zu XML-Behandlung

Beitrag von Mathias »

Vielen Dank für dein Beispiel.

Das mit dem nil am Anfang hatte ich auch mal probiert, aber dann ist er immer abgeschmiert. Irgendwie hat "GetFirstChild" Probleme gemacht.
Wen ich GetFirstChild durch treeNode := TreeView1...AddChild(... austausche , dann klappt es.
Ich habe mal die Images wegelassen, aber dies werde ich noch einbauen.

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
var
  doc: TXMLDocument;

  procedure Node(ADOMNode: TDOMNode; ATreeNode: TTreeNode);
  var
    j: integer;
    child: TDOMNode;
    treeNode: TTreeNode;
  begin
    if ADOMNode.NodeName = '#text' then begin
      treeNode := TreeView1.Items.AddChild(ATreeNode, ADOMNode.NodeValue);
    end else begin
      treeNode := TreeView1.Items.AddChild(ATreeNode, ADOMNode.NodeName);
    end;

    if ADOMNode.HasAttributes then begin
      for j := 0 to ADOMNode.Attributes.Length - 1 do begin
        TreeView1.Items.AddChild(treeNode,
          ADOMNode.Attributes.Item[j].NodeName + '= "' +
          ADOMNode.Attributes.Item[j].NodeValue + '"');
      end;
    end;

    child := ADOMNode.FirstChild;
    while child <> nil do begin
      Node(child, treeNode);
      child := child.NextSibling;
    end;

  end;

begin
  TreeView1.Items.Clear;
  ReadXMLFile(doc, path);
  Node(doc.DocumentElement, nil);
  doc.Free;
  TreeView1.FullExpand;
end;   
Noch ein kleines anderes Problem, ich habe deine Format(... Zeile ausprobiert, dort wird das hintere " verschluckt. Das sieht man auch bei deinem Screenshot. Wen ich ein zweites " reinschreibe geht es.

Code: Alles auswählen

Format('%s = "%""', ...
Woran liegt dies ?

Ich habe noch was in deinem Beispiel eindeckt, das ".Item" braucht es anscheinend bei den Attributen nicht.
Ich habe gerade festgestellt, beim Beispiel mit den Listen(Button1Click), kann man die ".Item" bei dem DOMListen auch weglassen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4888
Registriert: Fr 8. Apr 2011, 09:01

Re: Fragen zu XML-Behandlung

Beitrag von wp_xyz »

Mathias hat geschrieben:
So 31. Mai 2020, 13:42
Noch ein kleines anderes Problem, ich habe deine Format(... Zeile ausprobiert, dort wird das hintere " verschluckt. Das sieht man auch bei deinem Screenshot. Wen ich ein zweites " reinschreibe geht es.

Code: Alles auswählen

Format('%s = "%""', ...
Woran liegt dies ?
Weil ich das "s" hinter dem 2. "%" vergessen habe...

Code: Alles auswählen

Format('%s = "%s"', ...
Mathias hat geschrieben:
So 31. Mai 2020, 13:42
Ich habe noch was in deinem Beispiel eindeckt, das ".Item" braucht es anscheinend bei den Attributen nicht.
Ich habe gerade festgestellt, beim Beispiel mit den Listen(Button1Click), kann man die ".Item" bei dem DOMListen auch weglassen.
.Item[] ist die default-property, d.h. man kann es weglassen:

Code: Alles auswählen

type
  TDOMNodeList = class(TObject)
  protected
    ...
    function GetItem(index: LongWord): TDOMNode;
  public
    ...
    property Item[index: LongWord]: TDOMNode read GetItem; default;   // <---- siehe "default"
  end;

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Fragen zu XML-Behandlung

Beitrag von Mathias »

Was ist das für eine XML-Datei ?
Man beachte "edc:".

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8" standalone="no"?><edc:PIC xmlns:edc="http://crownking/edc" xmlns:atdf="http://crownking/atdf" xmlns:ltx="http://crownking/ltx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" atdf:architecture="AVR8" atdf:family="tinyAVR" edc:arch="avr8" edc:hasfreeze="false" edc:name="ATtiny13" edc:procid="0x0000" xsi:schemaLocation="http://crownking/edc edc/PIC.xsd">
  <edc:Power>
    <edc:VDD edc:maxvoltage="5.5" edc:minvoltage="1.8" edc:nominalvoltage="5.000"/>
  </edc:Power>
  ....
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Fragen zu XML-Behandlung

Beitrag von Socke »

Es handelt sich hier um Namensräume: https://de.wikipedia.org/wiki/Namensraum_(XML)
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten