XML Datei mit mehreren Kindelemente einlesen

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
SteffenD
Beiträge: 1
Registriert: Mo 3. Jul 2017, 18:48

XML Datei mit mehreren Kindelemente einlesen

Beitrag von SteffenD »

Hallo,

ich möchte gerne eine xml-Datei einlesen. Das klappt auch fast. Ich scheitere daran wenn die xml datei mehrere "Kindelemente" hat.
so sieht meine xml Datei aus

Code: Alles auswählen

 
<Komplett>
    <Eltern>
     <Kind>
      <KindVomKind1>1</KindVomKind1>
      <KindVomKind2>2</KindVomKind2>
      <KindVomKind3>3</KindVomKind3>
      <KindVomKind4>4</KindVomKind4>
     </Kind>
    </Eltern>
 </Komplett>
 


Hier ist mein Quellcode:

Code: Alles auswählen

 
procedure TForm1.ButtonEinlesenClick(Sender: TObject);
var
  Documento: TXMLDocument;
  i, j: Integer;
begin
  ReadXMLFile(Documento, 'test.xml');
  Memo.Lines.Clear;
 
  with Documento.DocumentElement.ChildNodes do
  begin
    for i := 0 to (Count - 1) do
    begin
       Memo.Lines.Add(Item[i].NodeName );
      for j := 0 to (Item[i].ChildNodes.Count - 1) do
      begin
        Memo.Lines.Add('-' + Item[i].ChildNodes.Item[j].NodeName);
        Memo.Lines.Add('--' + Item[i].ChildNodes.Item[j].FirstChild.NodeName);
        Memo.Lines.Add('---' + Item[i].ChildNodes.Item[j].FirstChild.NodeValue);
 
      end;
    end;
  end;
  Documento.Free;
end;                 
 
 


die Ausgabe sieht dann so aus:

Code: Alles auswählen

 
Eltern
-Kind
--KindVomKind1
---
 


Der Wert "1" von Position "kindVonKind1" wird nicht angezeigt. Ich möchte gerne hierbei alle Elemente in dem Memo ausgeben lassen.
Hat jemand eine Idee wie ich das umsetzen kann??

Gruß
Steffen

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

Re: XML Datei mit mehreren Kindelemente einlesen

Beitrag von wp_xyz »

Die Werte 1, 2, 3, 4 zwischen <KindVomKind> und </KindVomKind> sind wiederum eigene Nodes mit dem Namen #text. das heißt: du musst vom Node <KindVomKind> aus nochmals Firstchild aufrufen und kommst erst dann ans Ziel (http://wiki.lazarus.freepascal.org/XML_ ... _text_node):

Code: Alles auswählen

function GetNodeValue(ANode: TDOMNode): String;
begin
  Result := '';
  if (ANode = nil) then
    exit;
  ANode := ANode.FirstChild;
  if (ANode = nil) or (ANode.NodeName <> '#text') then
    exit;
  Result := ANode.NodeValue;
end;

Weiterhin finde ich ungeschickt, dass du das Dokument mit for-Schleifen über die ChildNodes[] durchläufst, denn damit stößt du leicht an die Grenzen, wenn die Nodes tief ineinandergeschachtelt sind. Außen hast du die i-Schleife für die obersten Nodes, dann brauchst du die j-Schleife für die Nodes der obersten Nodes. Die haben aber auch wieder Kinder, und die frägst du schon gar nicht mehr ab und hörst beim FirstNode auf. Nimm stattdessen einen rekursiven Algorithmus, wo ein Node seine direkten Kinder durchläuft und für jedes Kind sich wieder selbst aufruft. Eine wunderbare Gehirnübung, glaub's mir! Ein Beispiel findest du im xml-Tutorial hier: http://wiki.lazarus.freepascal.org/XML_ ... w_with_XML

Antworten