![]() |
XML Problem beim Einlesen
Jetzt habe ich's geschafft eine XML-Datei in etwa so zu schreiben wie ich will:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <test> <applicant_1> <family_name>Meyer</family_name> <given_name>Harald</given_name> <testdate>13.03.2009</testdate> <language>english</language> <WR_RW>229</WR_RW> </applicant_1> </test> ich kriege aber die Daten nicht wieder eingelesen, was ist hier falsch?
Delphi-Quellcode:
außerdem: wenn die Datei nicht da ist und ich sie neu erzeugen muß: muß ich immer die gleichenvar app:IXMLNode; begin XMLDocument1.LoadFromFile('d:\test.xml'); ListBox1.Items.Clear; For i := 1 to 5 do begin app:=XMLDocument1.DocumentElement.ChildNodes['applicant_'+IntToStr(i)]; //hier gibt es eine Zugriffsverletzung, warum? ListBox1.Items.Add(app.ChildNodes['family_name'].text); end; XMLDocument1.Free; end; Prozeduren aufrufen um die Struktur zu erzeugen? Wie kann ich einen Wert einer eingelesenen XML-Datei ändern?
Delphi-Quellcode:
?
app.ChildNodes['family_name'].text:='Schulze'
|
Re: XML Problem beim Einlesen
Zitat:
Keine Ahnung. Bei mir verursacht dein Code keinerlei Zugriffsverletzngen. Welche Exception wird denn bei dir ausgelöst? (den Fehlertext bitte mal nennen) PS: Strg+C kopiert den Text des Fehlerdialogs in die Zwischenablage, wenn er grad aktiv ist und man kann ihn dann direkt als text hier einfügen. OK, was mich erst gewundert hat ist, daß der Code nicht mindestens im zweiten Durchgang eine Exception wirft, aber in der nächsten Zeile erst. Allerdings ist bei der Komponente standardmäßig doNodeAutoCreate gesetzt, was dieses dann erklärte. Zitat:
aber Ja? Zitat:
|
Re: XML Problem beim Einlesen
Danke für den Kommentar himitsu - mit XML haben hier scheinbar nicht wo viele was am Hut.
Im Forum sind viele Threads die ohne Lösung enden. Also: der Grund für das (scheinbare) Nicht-Funktionieren war, daß ich in ListBox1 reingeschrieben habe, mein Blick aber auf die dafür extra eingerichtete ListBox2 geheftet war. :wall: Die Exception kam beim zweiten Aufruf, denn am Ende des ersten Aufrufs steht: XMLDocument1.Free; mit Zitat:
Ich versuche das jetzt über den EDOMParseError zu erreichen, der angeblich bei Active:=true erzeugt wird.
Delphi-Quellcode:
Wenn die Datei vorhanden ist (text.xml ist vorhanden, texst.xml nicht) listet er die Inhalte auf,
procedure TForm2.Button7Click(Sender: TObject);
var i:integer; app:IXMLNode; begin try XMLDocument1.LoadFromFile('d:\texst.xml'); XMLDocument1.Active := True; except On E: EDOMParseError do begin XMLDocument1.Version := '1.0'; XMLDocument1.StandAlone := 'yes'; //hier kommt jetzt die Zugriffsverletzung: XMLDocument1.Encoding := 'UTF-8'; XMLDocument1.Options := [doNodeAutoIndent]; XMLDocument1.AddChild('WRT'); XMLDocument1.SaveToFile('d:\Texst.xml'); end; end; //XMLDocument1.Active:=true; ListBox2.Items.Clear; ListBox2.Items.Add(XMLDocument1.DocumentElement.NodeName); for i := 1 to 5 do begin app:=XMLDocument1.DocumentElement.ChildNodes['applicant_'+IntToStr(i)]; ListBox2.Items.Add(app.ChildNodes['family_name'].text); end; XMLDocument1.Active:=false; end; ist sie nicht vorhanden kommt folgende Zugriffsverletzung: --------------------------- Benachrichtigung über Debugger-Exception --------------------------- Im Projekt test_xml.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 0049935B in Modul 'test_xml.exe'. Lesen von Adresse 00000000' aufgetreten. --------------------------- Anhalten Fortsetzen Hilfe --------------------------- Ich wollte an der Stelle an der klar ist, daß etwas mit der Datei nicht stimmt, die Struktur neu erzeugen um sie dann weiter zu befüllen. Deine Bemerkung über doNodeAutoCreate kann ich nicht nachvollziehen, warum sollte diese Option eine Exception erzeugen? |
Re: XML Problem beim Einlesen
Wegen des doNodeAutoCreate: Ich hatte irgendwie im Hinterkopf, daß in TXMLDocument dieses per Standard nicht gesetzt ist, aber wie ich grad sehe, ist dieses doch der Fall (kann aber auch sein, daß anderer Arten der Erzeugung eines Dokuments da andere Voreinstellungen haben :gruebel: )
Nja, jedenfalls gäbe es ohne diese Option eine Exception, da du ungeprüft auf applicant_1 bis applicant_5 zugreifst, es aber nur die applicant_1 in dem Dokument gibt. Sooo, also theoretisch würde/könnte man bei TXMLDocument so eine Datei erstellen
Delphi-Quellcode:
Und ich hätte dieses auch so in die Exceptionbehandlung aufgenommen.
XMLDocument1.Active := True;
XMLDocument1.Version := '1.0'; XMLDocument1.StandAlone := 'yes'; XMLDocument1.Encoding := 'UTF-8'; XMLDocument1.Options := [doNodeAutoIndent]; XMLDocument1.AddChild('WRT'); XMLDocument1.SaveToFile('d:\Test.xml'); PS: LoadFromFile lößt die Exception schon aus und würde nach erfolgreichem Parsen .Active auf True setzen. Demnach wäre ein Exprizites .Active:=True, nach erfolgreichem Parsen garnicht nötig. .Active := True; müßte man dan aber machen, wenn man das Dokument nun nach der Exception (neu) erstellen will, da die nachfolgenden Befehle nur in einem aktiven Element richtig ausgeführt werden. Das Fazit wäre also
Delphi-Quellcode:
Leider geht das aber nicht, wenn zuvor eine Exception in dieser Klasse aufgetreten ist, weil da anscheinend immernoch noch der defekte, bzw. leere XML-Text im Dokument drinsteckt und das Aktivieren + nochmal Parsen nun die Exception erneut aufrufen würde.
var i: integer;
app: IXMLNode; begin try XMLDocument1.LoadFromFile('d:\texst.xml'); except on E: EDOMParseError do begin XMLDocument1.Active := True; XMLDocument1.Version := '1.0'; XMLDocument1.StandAlone := 'yes'; XMLDocument1.Encoding := 'UTF-8'; XMLDocument1.Options := [doNodeAutoIndent]; XMLDocument1.AddChild('WRT'); XMLDocument1.SaveToFile('d:\texst.xml'); end; end; Leider find ich aber keinen Weg TXMLDocument irgendwie zurückzusetzen (sowas wie .Clear z.B. ) :wall: Gut, eine Lösung wäre nun einfach ein korrektes Dokument direkt reinzuladen. :angel2: z.B.:
Delphi-Quellcode:
Wenn jetzt noch weitere Subnodes direkt rein sollen, dann könnte man diese jetzt mit in diesen XML-Text einfügen oder sie danach z.B. via .AddChild hinzuzufügen.
var i: integer;
app: IXMLNode; begin try XMLDocument1.LoadFromFile('d:\texst.xml'); except on E: EDOMParseError do begin XMLDocument1.LoadFromXML('<?xml version="1.0" encoding="UTF-8" standalone="yes"?><WRT/>'); XMLDocument1.SaveToFile('d:\texst.xml'); end; end; |
Re: XML Problem beim Einlesen
grandioser Trick, jetzt habe ich sogar den Sinn des "LoadFromXML" verstanden.
Zitat:
ein Element eintragen oder eine vorhandene um eines ergänzen. Klappt hervorragend.
Delphi-Quellcode:
procedure TForm2.Button5Click(Sender: TObject); //add one XML
var i:integer; app_new:IXMLNode; begin try XMLDocument1.LoadFromFile('d:\test.xml'); except on E: EDOMParseError do begin XMLDocument1.LoadFromXML('<?xml version="1.0" encoding="UTF-8" standalone="yes"?><WRT/>'); XMLDocument1.SaveToFile('d:\test.xml'); end; end; i:=XMLDocument1.DocumentElement.ChildNodes.Count+1; app_new:=XMLDocument1.DocumentElement.AddChild('applicant_' + IntToStr(i)); app_new.AddChild('family_name'); app_new.AddChild('given_name'); app_new.AddChild('testdate'); app_new.AddChild('language'); app_new.ChildValues['family_name']:='Meyer'+ IntToStr(i); app_new.ChildValues['given_name']:='Harald'; app_new.ChildValues['testdate']:='13.03.2009'; app_new.ChildValues['language']:='english'; XMLDocument1.SaveToFile('d:\Test.xml'); end; Warum aber ist in der XML-Datei (im Gegensatz zu der in Einzelschritten erzeugten) kein Linefeed? (und kein schönes Auto-Indent) edit: Fehler gefunden, ich mußte bei der Neu-Erstellung noch mal
Delphi-Quellcode:
einfügen.Seltsam eigentlich, das war in den Optionen im Objektinspektor eigentlich so eingestellt...
XMLDocument1.Options:=[doNodeAutoIndent];
<?xml version="1.0" standalone="yes"?> <WRT><applicant_1><family_name>Meyer1</family_name><given_name>Harald</given_name>......... Großen Dank für die Hilfe! |
Re: XML Problem beim Einlesen
MSXML ist da etwas eigen.
Die Option doNodeAutoIndent sorgt erstmal für das AutoIdent (Zeilenumbruch+Einrückung), aber nur für neu erstellte Nodes (möchte man das nachträglich ändern, dann muß man praktisch das ganze Dokument neu aufbauen ... gibt hierzu aber schon ein/zwei Threads) Also in deinem Fall dürfte es reichen, wenn du einfach im OI bei Options dieses noch mit einträgst. (Diese Option ist zur Speicherersparnis dort standardmäßig deaktiviert) Options des TXMLDocument (z.B. im OI) [doNodeAutoCreate,doNodeAutoIndent,doAttrNull,doAut oPrefix,doNamespaceDecl] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz