XML Datei einlesen

Für Fragen von Einsteigern und Programmieranfängern...
BeniBela
Beiträge: 320
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: XML Datei einlesen

Beitrag von BeniBela »

Am besten geht das übrigrens mit meinen Internet Tools:

Die Frage ist, was du auswerten willst. Wenn du z.B.: zählen willst, wieviele Elemente mit Namen <foobar> existieren, geht das mit einer Zeile:

Code: Alles auswählen

process('http://undsoweiter/test.xml', 'count(//foobar)').toString

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: XML Datei einlesen

Beitrag von Scotty »

Hast du Documento irgendwo erzeugt? Free sehe ich, aber Create nicht...

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

Re: XML Datei einlesen

Beitrag von theo »

Scotty hat geschrieben:Hast du Documento irgendwo erzeugt? Free sehe ich, aber Create nicht...
Falsch. ADoc ist ein out Parameter in ReadXMLFile und wird in der Prozedur erzeugt.
Es vorher zu erzeugen würde ein Speicherleck verursachen.

hbr
Beiträge: 321
Registriert: Mi 20. Feb 2013, 10:30
OS, Lazarus, FPC: Win (L 2.2.4 FPC 3.2.2)
CPU-Target: 32/64,ARM(RPi)

Re: XML Datei einlesen

Beitrag von hbr »

Hallo Forum,
ich habe da noch ein Problem mit dem Auslesen, bzw. Bestimmen von xml Inhalte.
Kann einfach keine Funktion finden die mir ein "Elternelement" und die dazugehörigen "Kindelemente" ausliest, die Anzahl der Kindelemente können in der XML-Datei variieren.
Bei Delphie war das mit der Unit XMLFormat mit zwei befehlen zu realisieren.
string := Getprogramme(Doc);
IXMLProgrammType := xmldata.programm[ID1].kind3;
Ich suche also eine Funktion,Funktionsaufruf die mir wenn ich eine Elternelement z.B. mit ID=12 suche das die dazugehörenden Kinder oder auch einzelkind ausgegeben werden.
Gibt es so etwas auch bei Lazarus?

Mein XML ist so aufgebaut.

Code: Alles auswählen

<Programme>
  <Elternelement ID="1"> 
     <Kind1>abc</Kind1>
     <Kind2>abc</Kind2>
     <Kind3>abc</Kind3>
     <Kind4>abc</Kind4>
 </Elternelement>
 <Elternelement ID=2> 
     <Kind1>abc</Kind1>
     <Kind2>abc</Kind2>
     <Kind3>abc</Kind3>
 </Elternelement>
 <Elternelement ID=3> 
     <Kind1>abc</Kind1>
     <Kind2>abc</Kind2>
     <Kind3>abc</Kind3>
     <Kind4>abc</Kind4>
     <Kind5>abc</Kind5>
     <Kind6>abc</Kind6>
  </Elternelement>
</Programme>
Ach so, ist das Normal, das "Writeln('Test')" eine Fehlermelung produziert?
Beim einbinden von der "Unit CRT" verschwindet die Fehlermeldung, aber es wird nichts angezeigt.
Alles auf Win7 64Bit.

Für Antworten währe ich Dankbar.

Gruß

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

Re: XML Datei einlesen

Beitrag von theo »

Dein "Delphie" Beispiel verstehe ich grad nicht, aber hast du das schon durch?
http://wiki.freepascal.org/XML_Tutorial/de

hbr
Beiträge: 321
Registriert: Mi 20. Feb 2013, 10:30
OS, Lazarus, FPC: Win (L 2.2.4 FPC 3.2.2)
CPU-Target: 32/64,ARM(RPi)

Re: XML Datei einlesen

Beitrag von hbr »

theo hat geschrieben:Dein "Delphie" Beispiel verstehe ich grad nicht, aber hast du das schon durch?
http://wiki.freepascal.org/XML_Tutorial/de
Ja, hab ich!

Noch einmal zu Delphi.
Bei Delphie war das mit der Unit XMLFormat mit zwei befehlen zu realisieren.
--------------------------
Var Ergebnis : String;
doc: IXMLDocument;
xmldata: IXMLProgrammeType;
-----------------------------
xmldata := Getprogramme(Doc);
Ergebnis := xmldata.programm[ID1].kind1;
Mein gesuchtes "kind1" vom Block ("Elternelement" = ID1) steht in -> Ergebnis.

Bei dem Beispiel wird alles in einem Rutsch in eine Memo geschrieben.


So wie das aussieht muß man hier sich wohl einen eigen Parser schreiben, dass kann aber doch nicht war sein!
Hier muß es doch auch irgendwelche Funktionen geben, aber die finde ich leider nicht.

Gruß

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

Re: XML Datei einlesen

Beitrag von theo »

hbr hat geschrieben:
theo hat geschrieben:Dein "Delphie" Beispiel verstehe ich grad nicht, aber hast du das schon durch?
http://wiki.freepascal.org/XML_Tutorial/de
Ja, hab ich!
Aber dieses Beispiel zeigt dir doch, wie du durch den Baum rattern kannst und Namen sowie Attribute auslesen kannst.
http://wiki.freepascal.org/XML_Tutorial ... notennamen

hbr
Beiträge: 321
Registriert: Mi 20. Feb 2013, 10:30
OS, Lazarus, FPC: Win (L 2.2.4 FPC 3.2.2)
CPU-Target: 32/64,ARM(RPi)

Re: XML Datei einlesen

Beitrag von hbr »

Hallo,
ja richtig, wie Du so schreibst durchrattern.
theo hat geschrieben:Aber dieses Beispiel zeigt dir doch, wie du durch den Baum rattern kannst und Namen sowie Attribute auslesen kannst.
Und dann wenn ein "Kind" 100 mal in einem xml vorkommt, muss man es selbst raus filtern zu welchem Elternteil es gehört.

Deswegen mein vorheriges Beispiel mit der Delphi Unit, wo man ein bestimmtes Elternteil angeben kann und dann das dazu gehörige Kind bekommst.

Meine Frage war, welcher Befehl oder Funktion dieses unter Lazarus macht.

Sicherlich kann man die Komplette xml durch rattern, auswerten um das passendes kind zu finden, aber da für gibt es doch Funktionen, oder nicht?
Muss ich mir denn dafür doch einen Parser schreiben?

Gruß

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

Re: XML Datei einlesen

Beitrag von theo »

hbr hat geschrieben: Und dann wenn ein "Kind" 100 mal in einem xml vorkommt, muss man es selbst raus filtern zu welchem Elternteil es gehört.
Nein, du suchst das interessierende Elternteil unter Programme und nur in diesem Elternteil suchst du das Kind.
Kann doch nicht so schwierig sein?
hbr hat geschrieben: Deswegen mein vorheriges Beispiel mit der Delphi Unit, wo man ein bestimmtes Elternteil angeben kann und dann das dazu gehörige Kind bekommst.
Kannst du mir die Delphi Unit mal zeigen, die so funktioniert wie du es oben zeigst? Diese Syntax kann ich fast nicht glauben.
hbr hat geschrieben: Meine Frage war, welcher Befehl oder Funktion dieses unter Lazarus macht.
Du brauchst nicht schreien.
Es gibt eine Unit XPath, vllt. kommst du damit weiter. Ich kann dir dabei aber nicht helfen.
hbr hat geschrieben: Muss ich mir denn dafür doch einen Parser schreiben?
Warum nicht? Das wäre sicherlich eine sehr gute Übung.

P.S. Vllt.hilft das: http://lazarus.freepascal.org/index.php ... 13830.html

hbr
Beiträge: 321
Registriert: Mi 20. Feb 2013, 10:30
OS, Lazarus, FPC: Win (L 2.2.4 FPC 3.2.2)
CPU-Target: 32/64,ARM(RPi)

Re: XML Datei einlesen

Beitrag von hbr »

Hallo,
Danke für Deine Info.
Theo hat geschrieben: Du brauchst nicht schreien.
Es gibt eine Unit XPath, vllt. kommst du damit weiter. Ich kann dir dabei aber nicht helfen.
Ich schreie nicht, ich frage nur weil ich nichts finden kann und schon sehr lange suche.
Warum soll man ein Rad neu erfinden wenn es ewentuell schon vorhanden ist.
Darum Frage ich, weil vieleicht jemand da ist der Bescheid weis.

Ich möchte halt meine Delphie Programme auf Lazarus Portieren,
aber ich bin zu 95% damit beschäftigt neue oder vergleichbare Funktionen zu suchen oder zu erstellen.

Weis den niemand eine Anwort darauf, warum z.B. Writeln auf einem win7 64Bit nicht Funktioniert?
Habe ich im vorherigen Post gefragt.


Gruß

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: XML Datei einlesen

Beitrag von Michl »

Auf der Console sollte "Writeln" eigentlich gehen. Auch bei Win7 64Bit!

Da Du Deinen Fehler nicht genau erläuterst, kann man nur erahnen, dass dieser Fehler evtl. auftaucht >Projekt project1 hat Exception-Klasse >>RunError(103)<< ausgelöst<.

Falls dies der Fall ist, habe ich hier mal einen Link für Dich:
http://www.mail-archive.com/lazarus@laz ... 03465.html

mfg michl

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

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

Re: XML Datei einlesen

Beitrag von theo »

hbr hat geschrieben: Ich schreie nicht, ich frage nur weil ich nichts finden kann und schon sehr lange suche.
Warum soll man ein Rad neu erfinden wenn es ewentuell schon vorhanden ist.
Die andere Frage ist, ob es Sinn macht "sehr lange zu suchen" nur um sich einen 7-Zeiler zu ersparen?

hbr hat geschrieben: Weis den niemand eine Anwort darauf, warum z.B. Writeln auf einem win7 64Bit nicht Funktioniert?
Habe ich im vorherigen Post gefragt.
Writeln braucht eine Konsole auf Windows. Mach bei Projekteinstellungen -> Linken mal den Haken bei "Win32-GUI-Anwendung" weg.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: XML Datei einlesen

Beitrag von Michl »

Ok, oder statt Writeln soetwas wie Messagebox nutzen!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

hbr
Beiträge: 321
Registriert: Mi 20. Feb 2013, 10:30
OS, Lazarus, FPC: Win (L 2.2.4 FPC 3.2.2)
CPU-Target: 32/64,ARM(RPi)

Re: XML Datei einlesen

Beitrag von hbr »

theo hat geschrieben:Writeln braucht eine Konsole auf Windows. Mach bei Projekteinstellungen -> Linken mal den Haken bei "Win32-GUI-Anwendung" weg.
Vielen Dank!

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

Re: XML Datei einlesen

Beitrag von theo »

Hatte gerade Zeit, und würde sagen, 7 Minuten programmieren reicht.
Ist doch besser als "sehr lange suchen".

Code: Alles auswählen

function ExtractAttrName(Doc: TXMLDocument;ID,Name:WideString):WideString;
var
  an: TDOMNode;
  cn: TDOMNodeList;
  i: Integer;
begin
  cn:=Doc.DocumentElement.ChildNodes;
  for i:=0 to cn.count-1 do
   if cn.Item[i].Attributes.GetNamedItem('ID').NodeValue=ID then
     begin
       an:=cn.Item[i].FindNode(Name);
       if assigned(an) then
          begin
            result:=an.FirstChild.NodeValue;
            exit;
          end;
     end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Documento: TXMLDocument;
begin
  ReadXMLFile(Documento, 'test.xml');
  ShowMessage(UTF8Encode(ExtractAttrName(Documento,'2','Kind3')));
  Documento.Free;
end;    
Am besten mit diesen Daten, dann sieht man auch was:

Code: Alles auswählen

<Programme>
  <Elternelement ID="1"> 
     <Kind1>abc11</Kind1>
     <Kind2>abc12</Kind2>
     <Kind3>abc13</Kind3>
     <Kind4>abc14</Kind4>
 </Elternelement>
 <Elternelement ID="2"> 
     <Kind1>abc21</Kind1>
     <Kind2>abc22</Kind2>
     <Kind3>abc23</Kind3>
 </Elternelement>
 <Elternelement ID="3"> 
     <Kind1>abc21</Kind1>
     <Kind2>abc22</Kind2>
     <Kind3>abc23</Kind3>
     <Kind4>abc24</Kind4>
     <Kind5>abc25</Kind5>
     <Kind6>abc26</Kind6>
  </Elternelement>
</Programme>

Antworten