Sign in Join
Wiki copytemporary

XML Tutorial/de: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: XML Tutorial/de

OldNewLine
1+Zurück zu den [[Additional information/de|Zusätzlichen Informationen]].\
2+
3+== Einleitung ==
4+
5+Die Extensible Markup Language ist eine von [W3C](http://www.w3.org/) empfohlene Sprache, die für den Informationsaustausch zwischen verschiedenen Systemen geschaffen wurde. Sie ist eine textbasierte Möglichkeit, um Informationen zu speichern. Moderne Datenaustauschsprachen wie XHTML, ebenso wie die meisten WebServices Technologien, basieren auf XML.
6+
7+Gegenwärtig gibt es eine Reihe von Units, die XML unter Free Pascal unterstützen. Diese Units sind "XMLRead", "XMLWrite" und "DOM" und sind ein Teil der Free Component Library (FCL) des Free Pascal Compilers. Die FCL ist bereits im Standard-Suchpfad für den Compiler in Lazarus. Daher müssen Sie nur die Units zu Ihrem uses Abschnitt hinzufügen, um die XML Unterstützung zu erhalten. Die FCL ist gegenwärtig (Oktober 2005) noch nicht dokumentiert. Daher hat dieses kurze Tutorial das Ziel, einen Einstieg in XML unter Verwendung dieser Units zu bieten.
8+
9+Das XML DOM (Document Object Model) ist eine Reihe standardisierter Objekte, die eine ähnliche Schnittstelle für die Benutzung von XML für verschiedene Sprachen und Systeme bieten. Der Standard spezifiziert nur die Methoden, Eigenschaften und andere Schnittstellen Teile des Objekts. Die Implementierung in verschiedenen Sprachen ist frei gelassen. Die FCL unterstützt gegenwärtig vollständig das [XML DOM 1.0](http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/).
10+
11+## Beispiele
12+
13+Unten finden Sie eine Liste von Beispielen zur XML-Datenmanipulation mit wachsender Komplexität.
14+
15+### Lesen eines Textknotens
16+
17+Für Delphi Programmierer: Wenn Sie mit TXMLDocument arbeiten, ist zu beachten, dass der Text innerhalb eines Knotens ein separater Textknoten ist. Deshalb müssen Sie auf den Text eines Knotens als separaten Knoten zugreifen. Gehen Sie zum Beispiel von folgender XML-Datei aus:
18+
19+``` xml
20+ <?xml version="1.0"?>
21+ <request>
22+ <request_type>PUT_FILE</request_type>
23+ <username>123</username>
24+ <password>abc</password>
25+ </request>
26+```
27+
28+Das folgende Code-Beispiel zeigt sowohl den richtigen als auch den falschen Weg, um den Wert eines Textknotens zu erhalten:
29+
30+``` pascal
31+ var
32+ PassNode: TDOMNode;
33+ Doc: TXMLDocument;
34+ begin
35+ // Einlesen der xml Datei
36+ ReadXMLFile(Doc, 'c:\xmlfiles\test.xml');
37+ // Abrufen des "password" Knotens
38+ PassNode := Doc.DocumentElement.FindNode('password');
39+ // Ausgeben des Wertes des gewählten Knotens
40+ WriteLn(PassNode.NodeValue); // wird leer sein
41+ // Der Text des Knotens ist ein separater Kindknoten
42+ WriteLn(PassNode.FirstChild.NodeValue); // gibt "abc" korrekt aus
43+```
44+
45+### Ausgeben der Knotennamen
46+
47+Das folgende Beispiel zeigt, wie man die Knotennamen in einem Memo (platziert auf einem Formular) ausgibt.
48+
49+Unterhalb sehen Sie die XML-Datei namens 'C:\Programas\teste.xml':
50+
51+``` xml
52+ <?xml version="1.0"?>
53+ <images directory="mydir">
54+ <imageNode URL="graphic.jpg" title="">
55+ <Peca DestinoX="0" DestinoY="0">Pecacastelo.jpg1.swf</Peca>
56+ <Peca DestinoX="0" DestinoY="86">Pecacastelo.jpg2.swf</Peca>
57+ </imageNode>
58+ </images>
59+```
60+
61+Und hier der Pascal Code um die Aufgabe auszuführen:
62+
63+``` pascal
64+ var
65+ Documento: TXMLDocument;
66+ i, j: Integer;
67+ begin
68+ ReadXMLFile(Documento, 'C:\Programas\teste.xml');
69+ Memo.Lines.Clear;
70+ with Documento.DocumentElement.ChildNodes do
71+ begin
72+ for i := 0 to (Count - 1) do
73+ begin
74+ Memo.Lines.Add(Item[i].NodeName + ' ' + Item[i].Attributes.Item[0].NodeValue);
75+ for j := 0 to (Item[i].ChildNodes.Count - 1) do
76+ begin
77+ Memo.Lines.Add(Item[i].ChildNodes.Item[j].NodeName + ' '
78+ + Item[i].ChildNodes.Item[j].FirstChild.NodeValue);
79+ end;
80+ end;
81+ end;
82+ Documento.Free;
83+ end;
84+```
85+
86+Dies führt zur Ausgabe von:
87+
88+ imageNode graphic.jpg
89+ Peca Pecacastelo.jpg1.swf
90+ Peca Pecacastelo.jpg1.swf
91+
92+### Füllen eines TreeView mit XML
93+
94+Eine übliche Verwendung von XML Dateien ist, sie zu analysieren und ihren Inhalt in einem baumartigen Format anzuzeigen. Sie können die TTreeView-Komponente auf dem "Common Controls" Tab von Lazarus finden.
95+
96+Die Funktion unten nimmt ein zuvor geladenes oder im Code erzeugtes XML-Dokument und füllt einen TreeView mit seinen Inhalten. Die Beschriftung jedes Knotens ist der Inhalt des ersten Attributs eines jeden Knotens.
97+
98+``` pascal
99+procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument);
100+var
101+ iNode: TDOMNode;
102+
103+ procedure ProcessNode(Node: TDOMNode; TreeNode: TTreeNode);
104+ var
105+ cNode: TDOMNode;
106+ begin
107+ if Node = nil then Exit; // Aufhören, wenn ein Blatt erreicht ist
108+
109+ // Einen Knoten zum Baum hinzufügen
110+ if Node.HasAttributes then
111+ TreeNode := tree.Items.AddChild(TreeNode, Node.Attributes[0].NodeValue)
112+ else
113+ TreeNode := tree.Items.Addchild(TreeNode, '');
114+
115+ // Zum Kindknoten weiter gehen
116+ cNode := Node.ChildNodes.Item[0];
117+
118+ // Alle Kindknoten bearbeiten
119+ while cNode <> nil do
120+ begin
121+ ProcessNoDe(cNode, TreeNode);
122+ cNode := cNode.NextSibling;
123+ end;
124+ end;
125+
126+begin
127+ iNode := XMLDoc.DocumentElement.ChildNodes.Item[0];
128+ while iNode <> nil do
129+ begin
130+ ProcessNode(iNode, nil); // Rekursiv
131+ iNode := iNode.NextSibling;
132+ end;
133+end;
134+```
135+
136+### Modifizieren eines XML-Dokuments
137+
138+Das wichtigste, was man sich merken muss ist, dass 'TDOMDocument' das "Handle" für DOM ist. Eine Instanz dieser Klasse erhält man, indem man eine erzeugt oder indem man ein XML-Dokument lädt.
139+
140+Dagegen können Knoten nicht wie normale Objekte erzeugt werden. Man muss die Methoden von TDOMDocument für die Erzeugung verwenden und sie danach mit anderen Methoden an die richtige Stelle zu bringen. Der Grund dafür ist, dass die Knoten einem speziellen Dokument auf DOM gehören müssen.
141+
142+Nachfolgend sind einige gebräuchliche Methoden von TDOMDocument:
143+
144+``` pascal
145+ function CreateElement(const tagName: DOMString): TDOMElement; virtual;
146+ function CreateTextNode(const data: DOMString): TDOMText;
147+ function CreateCDATASection(const data: DOMString): TDOMCDATASection;
148+ virtual;
149+ function CreateAttribute(const name: DOMString): TDOMAttr; virtual;
150+```
151+
152+Und jetzt eine Beispielsmethode, die das ausgewählte Element auf einem TTreeView lokalisiert und einen Kindknoten in das entsprechende XML-Dokument einfügt. Der TreeView muss vorher mit den Inhalten einer XML-Datei unter Verwendung der [[Networking|XML2Tree Funktion]] gefüllt werden.
153+
154+``` pascal
155+procedure TForm1.actAddChildNode(Sender: TObject);
156+var
157+ Posicao: Integer;
158+ NovoNo: TDomNode;
159+begin
160+ {*******************************************************************
161+ * Ausgewähltes Element bestimmen
162+ *******************************************************************}
163+ if TreeView1.Selected = nil then Exit;
164+
165+ if TreeView1.Selected.Level = 0 then
166+ begin
167+ Posicao := TreeView1.Selected.Index;
168+
169+ NovoNo := XMLDoc.CreateElement('item');
170+ TDOMElement(NovoNo).SetAttribute('nome', 'Item');
171+ TDOMElement(NovoNo).SetAttribute('arquivo', 'Arquivo');
172+ XMLDoc.DocumentElement.ChildNodes.Item[Posicao].AppendChild(NovoNo);
173+
174+ {*******************************************************************
175+ * Den TreeView updaten
176+ *******************************************************************}
177+ TreeView1.Items.Clear;
178+ XML2Tree(TreeView1, XMLDoc);
179+ end
180+ else if TreeView1.Selected.Level >= 1 then
181+ begin
182+ {*******************************************************************
183+ * Diese Funktion bearbeitet nur eine Ebene des Baumes,
184+ * kann aber leicht so geändert werden, dass eine beliebige Anzahl von Ebenen bearbeitet wird.
185+ *******************************************************************}
186+ end;
187+end;
188+```
189+
190+### Erzeugen eines TXMLDocument aus einem String
191+
192+Ist eine XML-Datei in MyXmlString gegeben, erzeugt der folgende Code Ihre DOM:
193+
194+``` pascal
195+Var
196+ S : TStringStream;
197+ XML : TXMLDocument;
198+
199+begin
200+ S:= TStringStream.Create(MyXMLString);
201+ Try
202+ S.Position:=0;
203+ XML:=Nil;
204+ ReadXMLFile(XML,S); // Komplettes XML-Dokument
205+ // Alternativ:
206+ ReadXMLFragment(AParentNode,S); // Nur das XML-Fragment lesen.
207+ Finally
208+ S.Free;
209+ end;
210+end;
211+```
212+
213+### Überprüfen der Gültigkeit der Struktur einer XML-Datei
214+
215+Seit März 2007 besitzt der FCL XML-Parser die Fähigkeit ein XML-Dokument anhand einer DTD zu überprüfen. Dabei wird überprüft, ob die logische Struktur des Dokumentes mit vordefinierten Regeln aus einer *Document Type Definition* (DTD) übereinstimmt. Diese Technik wird auch bei Webseiten mit HMTL angewendet.
216+
217+Hier ist ein kleines Beispiel einer XML-Datei mit interner DTD:
218+
219+``` xml
220+ <?xml version='1.0'?>
221+ <!DOCTYPE root [
222+ <!ELEMENT root (child)+ >
223+ <!ELEMENT child (#PCDATA)>
224+ ]>
225+ <root>
226+ <child>This is a first child.</child>
227+ <child>And this is the second one.</child>
228+ </root>
229+```
230+
231+Diese DTD legt als 'root' als Wurzelelement fest. Dieses Wurzelelement muss mindestens ein Kindelement mit dem Namen 'child' besitzen. Diese 'child'-Elemente dürfen nur Buchstaben (PCHDATA = parsed character data, verarbeite Buchstaben-Daten) enthalten. Wenn der Parser irgendwelche Abweichungen gegenüber diesen Regeln feststellt, wird er diese melden.
232+
233+Durch das Überprüfen der Dokumentstruktur ist das Laden der XML-Datei etwas komplizierter. In diesem Beispiel können wir auf die XML-Datei über ein TStream-Objekt zugreifen:
234+
235+``` pascal
236+procedure TMyObject.DOMFromStream(AStream: TStream);
237+var
238+ Parser: TDOMParser;
239+ Src: TXMLInputSource;
240+ TheDoc: TXMLDocument;
241+begin
242+ try
243+ // ein neues Parserobjekt erstellen
244+ Parser := TDOMParser.Create;
245+ // die XML-Datei muss über ein TXMLInputSource-Objekt geladen werden
246+ Src := TXMLInputSource.Create(AStream);
247+ // wir wollen eine Überprüfung der Dokumentstruktur
248+ Parser.Options.Validate := True;
249+ // Festlegen einer Methode, die bei Fehlern aufgerufen wird
250+ Parser.OnError := @ErrorHandler;
251+ // nun beginnen wir die Überprüfung
252+ Parser.Parse(Src, TheDoc);
253+ // ... und räumen hinterher wieder auf
254+ finally
255+ Src.Free;
256+ Parser.Free;
257+ end;
258+end;
259+
260+procedure TMyObject.ErrorHandler(E: EXMLReadError);
261+begin
262+ if E.Severity = esError then // wir sind nur in Fehlern bezüglich der Verletzung der DTD interessiert
263+ writeln(E.Message);
264+ // an dieser Stelle können wir auch alles andere machen, was bei einem Fehler getan werden sollte
265+end;
266+```
267+
268+### Whitespace-Zeichen
269+
270+Wenn Sie führende Whitespace-Zeichen in den Knotentexten erhalten wollen, dann ist obige Methode der richtige Weg zum Laden Ihres Dokuments. Führende Whitespace-Zeichen werden standardgemäß ignoriert. Dies ist der Grund, warum die Funktion 'ReadXML(...)' niemals die Whitespace-Zeichen in Knotentexten zurückgibt. Vor dem Aufruf von *Parser.Parse(Src, TheDoc)* fügen Sie folgende Zeile ein:
271+
272+``` pascal
273+Parser.Options.PreserveWhitespace := True;
274+```
275+
276+Dadurch zwingt man den Parser dazu, alle Whitespace-Zeichen zu übergeben. Dies schließt auch alle Zeilenendezeichen ein, die in einem XML-Dokument nur zur besseren Lesbarkeit stehen!
277+
278+### Erzeugen einer XML-Datei
279+
280+Nachfolgend ist der komplette Code für das Schreiben in eine XML-Datei. (Er wurde einem Tutorial des DeveLazarus-Blogs entnommen.) Bitte denken Sie an den Verweis auf die Bibliotheken DOM und XMLWrite in der 'uses'-Klausel.
281+
282+``` pascal
283+unit Unit1;
284+
285+{$mode objfpc}{$H+}
286+
287+interface
288+
289+uses
290+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
291+ DOM, XMLWrite;
292+
293+type
294+ { TForm1 }
295+ TForm1 = class(TForm)
296+ Button1: TButton;
297+ Label1: TLabel;
298+ Label2: TLabel;
299+ procedure Button1Click(Sender: TObject);
300+ private
301+ { private declarations }
302+ public
303+ { public declarations }
304+ end;
305+
306+var
307+ Form1: TForm1;
308+
309+implementation
310+
311+{ TForm1 }
312+
313+procedure TForm1.Button1Click(Sender: TObject);
314+var
315+ Doc: TXMLDocument; // Variable für das Dokument
316+ RootNode, parentNode, nofilho: TDOMNode; // Variable für die Elemente (Knoten)
317+begin
318+ try
319+ // Erzeuge ein Dokument
320+ Doc := TXMLDocument.Create;
321+
322+ // Erzeuge einen Wurzelknoten
323+ RootNode := Doc.CreateElement('register');
324+ Doc.Appendchild(RootNode); // sichere den Wurzelelement
325+ // Create a parent node
326+ RootNode:= Doc.DocumentElement;
327+ parentNode := Doc.CreateElement('usuario');
328+ TDOMElement(parentNode).SetAttribute('id', '001'); // erzeuge die Attribute für das Elternelement
329+ RootNode.Appendchild(parentNode); // sichere das Elternelement
330+
331+ // Create a child node
332+ parentNode := Doc.CreateElement('nome'); // erzeuge einen Kindelement
333+ // TDOMElement(parentNode).SetAttribute('sexo', 'M'); // erzeuge die Attribute
334+ nofilho := Doc.CreateTextNode('Fernando'); // füge einen Wert für den Knoten ein
335+ parentNode.Appendchild(nofilho); // sichere den Knoten
336+ RootNode.ChildNodes.Item[0].AppendChild(parentNode); // füge das Kindelement in das Elternelement ein
337+
338+ // Create a child node
339+ parentNode := Doc.CreateElement('idade'); // erzeuge einen Kindelement
340+ // TDOMElement(parentNode).SetAttribute('ano', '1976'); // erzeuge die Attribute
341+ nofilho := Doc.CreateTextNode('32'); // füge einen Wert für den Knoten ein
342+ parentNode.Appendchild(nofilho); // sichere den Knoten
343+ RootNode.ChildNodes.Item[0].AppendChild(parentNode); // füge das Kindelement in das Elternelement ein
344+
345+ writeXMLFile(Doc, 'test.xml'); // schreibe in die XML-Datei
346+ finally
347+ Doc.Free; // gib den Speicher frei
348+ end;
349+end;
350+
351+initialization
352+ {$I unit1.lrs}
353+
354+end.
355+```
356+
357+Das Ergebnis steht in folgender XML-Datei:
358+
359+``` xml
360+<?xml version="1.0"?>
361+<register>
362+ <usuario id="001">
363+ <nome>Fernando</nome>
364+ <idade>32</idade>
365+ </usuario>
366+</register>
367+```
368+
369+--Fernandosinesio 22:28, 24 April 2008 (CEST)fernandosinesio@gmail.com
370+
371+### Encoding
372+
373+Seit der SVN Revision 12582, ist der XML-Reader fähig, Daten in einer beliebigen Kodierung zu verarbeiten durch den Einsatz externer Dekoder. Siehe [[XML Decoders]] für weitere Details.
374+
375+Nach den XML-Standards ist das Encoding-Attribut in der ersten Zeile einer XML-Datei optional, falls die tatsächliche Kodierung UTF-8 oder UTF-16 ist (was durch Vorhandensein des BOM erkannt wird). In Lazarus Version 0.9.26 hat TXMLDocument eine Eigenschaft Encoding, die aber momentan ignoriert wird. writeXMLFile benutzt immer UTF-8 und erzeugt kein Encoding-Attribut in der ersten Zeile der XML-Datei.
376+
377+## Siehe auch
378+
379+- [[XML Decoders]]
380+- [[Using INI Files/de|Einsatz von INI-Dateien]]
381+- [[fcl-xml]]
382+
383+## Externe Links
384+
385+- [W3Schools](http://www.w3schools.com/xml/default.asp) Xml Tutorial
386+
387+- [Thomas Zastrows Artikel](http://www.thomas-zastrow.de/texte/fpcxml/index.php) [Alternativer Link](http://web.archive.org/web/20080802150722/http://www.thomas-zastrow.de/texte/fpcxml/index.php) FPC und XML
388+
389+---
390+*From the Free Pascal wiki, page "XML Tutorial/de", as it stood on 2020-03-02 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history