XML Auslesen

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

XML Auslesen

Beitrag von pascalts »

Hallöchen!

Ich bin gerade dabei Teile einer XML-Datei auszulesen. Klappt soweit ganz gut, nur komme ich nicht an den Teil ran, an den ich ran möchte :-)

Das ist der Teil der XML:

Code: Alles auswählen

<Machine Name="#KR210R2700 EXTRA C4 FLR" />


Ich möchte nun alles was hinter Name=" steht auslesen... Leider finde ich keinen Weg. Textknoten sind ja kein Problem...

Danke im Vorraus!
Zuletzt geändert von pascalts am Do 16. Okt 2014, 10:53, insgesamt 1-mal geändert.

relocate
Beiträge: 54
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4)
CPU-Target: 32Bit

Re: TDOMnode zu WideString

Beitrag von relocate »

Ist TypNode überhaupt gesetzt, es könnte nur ein Schreibfehler sein, aber Du suchst nach 'Machnine Name' ist das nicht eher 'Machine Name', ob TypNode gesetzt ist kann man mit assigned prüfen: if assigned(TypNode) then ..., so mache ich es zumindest.

pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Re: TDOMnode zu WideString

Beitrag von pascalts »

relocate hat geschrieben:Ist TypNode überhaupt gesetzt, es könnte nur ein Schreibfehler sein, aber Du suchst nach 'Machnine Name' ist das nicht eher 'Machine Name', ob TypNode gesetzt ist kann man mit assigned prüfen: if assigned(TypNode) then ..., so mache ich es zumindest.


Das war Fehler 1. Fehler 2 war, das ich etwas völlig falsches ausgelesen habe. Siehe EDIT des ersten Posts!

relocate
Beiträge: 54
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4)
CPU-Target: 32Bit

Re: XML Auslesen

Beitrag von relocate »

Das sind Attribute, müsste so gehen:

if TypNode.HasAttributes then begin
StringTyp := TypNode.Attributes.GetNamedItem('Name').NodeValue;

pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Re: XML Auslesen

Beitrag von pascalts »

Oh, das geht simpler und intuitiver als gedacht! Danke!

Resultat:

Code: Alles auswählen

ReadXMLFile(Doc, SelectDirectoryDialogAusgabe.FileName + '\Temp\' + lbROBOTERLISTE.Items[i] + '\C\KRC\Roboter\Config\System\Common\Mada\NGAxis\A1.xml');
TypNode := Doc.DocumentElement.FindNode('
Machine');
if TypNode.HasAttributes and (TypNode.Attributes.Length>0) then
 begin
   //ShowMessage(TypNode.Attributes[0].NodeValue)
   varBookmark := varDokument.Bookmarks.Item('
Robotertyp');
   varBookmark.Range.Text := TypNode.Attributes[0].NodeValue;
   end
else
ShowMessage('
Robotertyp nicht gefunden!')


Ich arbeite erst seit kurzem mit Lazarus und bin wirklich überrascht, welches Potential darin steckt... DAUMEN HOCH!

relocate
Beiträge: 54
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4)
CPU-Target: 32Bit

Re: XML Auslesen

Beitrag von relocate »

Ja, musste mich vor etwa zwei Monaten damit auseinandersetzen. Hab nach verschiedenen Möglichkeiten unter Delphi gesucht (bei meiner Version gibt es keine XML Komponente) und bin dann bei Free Pascal und deren LIB hängen geblieben. Die Erfolge hatten sich bereits nach ein paar Stunden Einarbeitung eingestellt. Ja, Thumbs up für FPC und Co.

pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Re: XML Auslesen

Beitrag von pascalts »

So... jetzt gibt es doch wieder murks. Das was oben steht funktioniert ja 1A. Aber bei einer 2ten Datei gibt es Probleme. Als erstes die komplette Datei:

Code: Alles auswählen

<?xml version="1.0" encoding="utf-8"?>
<RdcConfiguration Version="1.0" RobotName="K3A1G1524150R05" NetworkArchivePath="" DomainAndUser="" PassWord="Nug8zGQNi9E0dPKXT+WgSw==" />
(ja, das ist alles :-) )

Dementsprechend sieht meine Folge so aus:

Code: Alles auswählen

//Robotername
               begin
                ReadXMLFile(Doc2, SelectDirectoryDialogAusgabe.FileName + '\Temp\' + lbROBOTERLISTE.Items[i] + '\C\KRC\Roboter\Rdc\RobotData.xml' ); //Pfad stimmt, habe ich überprüft)
                NameNode := Doc2.DocumentElement.FindNode('
RdcConfiguration'); //RdcConfiguration gibt es auch, siehe oben...
                 if NameNode.HasAttributes and (NameNode.Attributes.Length>0) then  //Hier setzt das Programm aus...
                   begin
                      varBookmark := varDokument.Bookmarks.Item('
Robotername');
                      varBookmark.Range.Text := NameNode.Attributes[1].NodeValue;
                      robotername:=NameNode.Attributes[1].NodeValue;
                      ShowMessage(robotername);
                    end
                 else
                   ShowMessage('
Robotername nicht gefunden!');
                end; 


ABER: Das Programm steigt mitten drin aus... Zu allem Übel hängt sich dann auch noch der Debugger auf :cry: :cry: :cry: Jedes mal. Reproduzierbar...

relocate
Beiträge: 54
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4)
CPU-Target: 32Bit

Re: XML Auslesen

Beitrag von relocate »

Wie ich schon geschrieben habe, prüfen ob die Variable Assigned ist.
Ist der Aufbau der zweiten identisch mit der ersten?

pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Re: XML Auslesen

Beitrag von pascalts »

relocate hat geschrieben:Wie ich schon geschrieben habe, prüfen ob die Variable Assigned ist.
Ist der Aufbau der zweiten identisch mit der ersten?

Ja, der Aufbau ist, soweit ich mich nicht vertan habe, gleich. Wie prüfe ich das? Sorry von "assigned" hab ich noch nix gehört...

relocate
Beiträge: 54
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4)
CPU-Target: 32Bit

Re: XML Auslesen

Beitrag von relocate »

Aus der Delphi Hilfe:
Die Funktion Assigned prüft, ob ein Zeiger oder eine Prozedurvariable den Wert NIL hat (nicht zugewiesen ist).

(Deshalb habe ich ja assigned erwähnt oben). Einfach mit:

Code: Alles auswählen

 
if assigned(NameNode) then begin
{...}
end else showmessage('Fehler');
 

Es wird ja ein Objekt erzeugt, eine Variable auf ein Objekt ist im Prinzip auch nur ein Zeiger auf das Objekt, existiert das Objekt nicht, dann ist der Zeiger nil (was nicht zwingend gilt, wenn das Objekt existiert hat und zerstört wurde, ohne eben den Objektzeiger auf nil zu setzen, davon gehe ich jetzt aber mal nicht aus). Mit assigned prüft man nun vorher ob, in diesem Fall, NameNode überhaupt existiert, wenn das Objekt nämlich nicht existiert und du versuchst darauf zu zugreifen, kommt es nämlich zu solchen Fehlern.

Daher kannst Du prüfen ob NameNode existiert und wenn nicht, dann bricht das Programm nicht ab, wenn Du nicht auf die Variable anderweitig zugreifst. Existiert sie nicht, ist irgend etwas falsch gelaufen beim Versuch RdcConfiguration zu finden. Ob die XML Datei wirklich existiert prüfe ich mittels eines simplen FileExists, aber das scheint in Ordnung zu sein, da Du ja scheinbar auf Doc2 zugreifen kannst.

BeniBela
Beiträge: 270
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: XML Auslesen

Beitrag von BeniBela »

Sowas geht viel kürzer mit meinen Internet Tools

Code: Alles auswählen

uses simpleinternet;
showmessage(process(SelectDirectoryDialogAusgabe.FileName + '\Temp' + lbROBOTERLISTE.Items[i] + '\C\KRC\Roboter\Rdc\RobotData.xml' ,
                    '//RdcConfiguration/@RobotName' ).toString)
 


Und für <Machine Name="#KR210R2700 EXTRA C4 FLR" /> geht es mit //Machine/@Name

pascalts
Beiträge: 61
Registriert: Fr 10. Okt 2014, 13:16

Re: XML Auslesen

Beitrag von pascalts »

Also: Datei existiert - sagst zumindest

Code: Alles auswählen

if FileExists(SelectDirectoryDialogAusgabe.FileName + '\Temp\' + lbROBOTERLISTE.Items[i] + '\C\KRC\Roboter\Rdc\RobotData.xml') then
ShowMessage('
jo, is da.');


mit deinem Assigned wird die kritische Stelle natürlich übersprungen... hilft mir aber dahingehend nicht weiter, da es ja da ist und ich die stelle brauche :oops: :cry:

Hier nochmal der ganze Teil:

Code: Alles auswählen

//Robotername
 
                if FileExists(SelectDirectoryDialogAusgabe.FileName + '\Temp\' + lbROBOTERLISTE.Items[i] + '\C\KRC\Roboter\Rdc\RobotData.xml') then
                begin
                ShowMessage('
jo, is da.');
                ReadXMLFile(Doc2, SelectDirectoryDialogAusgabe.FileName + '
\Temp\' + lbROBOTERLISTE.Items[i] + '\C\KRC\Roboter\Rdc\RobotData.xml');
                NameNode := Doc2.DocumentElement.FindNode('
RdcConfiguration');
                if assigned(NameNode) then
                 begin
                    if NameNode.HasAttributes and (NameNode.Attributes.Length>0) then
                      begin
                       varBookmark := varDokument.Bookmarks.Item('
Robotername');
                       varBookmark.Range.Text := NameNode.Attributes[1].NodeValue;
                       robotername:=NameNode.Attributes[1].NodeValue;
                       ShowMessage(robotername);
                      end
                    else
                    ShowMessage('
Robotertyp nicht gefunden!');
                 end;
                end


Kann es irgendwie an der XML Datei liegen?

relocate
Beiträge: 54
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4)
CPU-Target: 32Bit

Re: XML Auslesen

Beitrag von relocate »

BeniBela hat geschrieben:Sowas geht viel kürzer mit meinen Internet Tools

Code: Alles auswählen

uses simpleinternet;
showmessage(process(SelectDirectoryDialogAusgabe.FileName + '\Temp' + lbROBOTERLISTE.Items[i] + '\C\KRC\Roboter\Rdc\RobotData.xml' ,
                    '//RdcConfiguration/@RobotName' ).toString)
 


Und für <Machine Name="#KR210R2700 EXTRA C4 FLR" /> geht es mit //Machine/@Name


Geht nicht alles, immer irgendwie auch besser?! :wink:
Ich versuche meist alles mit Boardmitteln und sogar zu Fuß, weil mir der Lerneffekt wichtig ist.

relocate
Beiträge: 54
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4)
CPU-Target: 32Bit

Re: XML Auslesen

Beitrag von relocate »

pascalts hat geschrieben:mit deinem Assigned wird die kritische Stelle natürlich übersprungen... hilft mir aber dahingehend nicht weiter, da es ja da ist und ich die stelle brauche :oops: :cry:


Darum geht es hier, Schritt für Schritt die Fehlerquelle zu ermitteln, wenn der Debugger einem dabei nicht weiter hilft.
Das Assigned zeigt hier ja, die Variable ist gar nichts zugewiesen. Jetzt muss man heraus finden wieso.

pascalts hat geschrieben:Kann es irgendwie an der XML Datei liegen?


Ich habe eine andere Vermutung, du sagst, es ist die zweite Datei, ist die Variable Doc2 nur für die zweite Datei oder wurde die schon für die erste Datei benutzt worden?! Es kann sein, dass readxmlfile mit einer Variable die noch in Benutzung ist nicht zusammen arbeitet. D.h. es ist eventuell immer noch die erste Datei gespeichert. Es würde mich wundern, wenn es an der XML Datei liegt, so simpel wie die aufgebaut ist.

gocher
Beiträge: 298
Registriert: Di 23. Nov 2010, 23:41
OS, Lazarus, FPC: Ubuntu/Win, Lazarus trunk, FPC trunk
CPU-Target: 32Bit/64Bit
Wohnort: Geldern
Kontaktdaten:

Re: XML Auslesen

Beitrag von gocher »

pascalts hat geschrieben:

Code: Alles auswählen

<?xml version="1.0" encoding="utf-8"?>
<RdcConfiguration Version="1.0" RobotName="K3A1G1524150R05" NetworkArchivePath="" DomainAndUser="" PassWord="Nug8zGQNi9E0dPKXT+WgSw==" />
...

Code: Alles auswählen

...
ReadXMLFile(Doc2, SelectDirectoryDialogAusgabe.FileName + '\Temp\' + lbROBOTERLISTE.Items[i] + '\C\KRC\Roboter\Rdc\RobotData.xml' ); //Pfad stimmt, habe ich überprüft)
NameNode := Doc2.DocumentElement.FindNode('
RdcConfiguration'); //RdcConfiguration gibt es auch, siehe oben...
... 

...

Ich bin zwar nicht mit der Variante vertraut da ich meine eigene DOM-Class entwickelt habe, aber ich würde sagen, "RdcConfiguration" ist das Root Element was bei meiner Klasse dem DocumentElement entspricht und wenn du darin suchst wirst Du nichts finden.
In dem Fall ist wahrscheinlich auch wie bei meiner Klasse NameNode := Doc2.DocumentElement;
MfG Gocher
akt. Projekt: Webserver(HTTPS HTTP/2) mit integrierten CMS in Free Pascal - www.gocher.me

Antworten