![]() |
|
URL dieses Artikels:
zu Ausgabe:
6.2003
Der universelle Transformer
Ein Blick auf den XML Data Binding Wizard von Delphi 7 Enterprise
von Andreas Kosch
XML als das universell transportierbare Datenformat ist in aller Munde und was noch wichtiger ist, auch in freier Wildbahn immer häufiger anzutreffen. Allerdings passt der kryptisch aussehende Inhalt einer derartigen XML-Datei nicht so recht in die schöne heile Welt des Rapid Application Development (RAD). Ich möchte Ihnen einen Weg vorstellen, der die Vorteile von XML nutzt, ohne dass der Entwickler seine gewohnte RAD-Umgebung von Delphi verlassen muss.
Bevor Sie nun aber gleich in euphorischen Jubel ausbrechen, sei ein Hinweis auf die Nebenwirkungen gestattet. Der Komfort steht nur dann zur Verfügung, wenn Sie die Enterprise-Version von Delphi nutzen. Angenommen, Sie bekommen von Ihrem Chef eine XML-Datei vorgesetzt, die von einem externen Kunden mit umfangreichen Datenmengen gefüllt wurde. Nun sollen Sie ein Programm schreiben, dass die in der XML-Datei vorgefundenen Informationen weiterverarbeitet. Um es so übersichtlich wie nur möglich zu gestaltet, hat in meinem Beispiel die XML-Datei einen sehr schlichten Aufbau. Dort tauchen nur drei Datensätze auf, die jeweils aus drei Spalten bestehen: <?xml version="1.0"?>Bereits der kurze Blick auf diesen Inhalt reicht aus, um die ersten Probleme ans Tageslicht zu bringen. Im Gegensatz zu einer richtigen Datenbank wird die Datenstruktur nicht exakt definiert. Sowohl der Datentyp einer Spalte als auch die Feldbreite kann aus den Daten allein nicht ermittelt werden. Es wird also in jedem Fall noch eine weitere Beschreibung benötigt, wobei ich in meinem Beispiel davon ausgehe, dass die Beschreibung nicht aus einer XML Schema-Datei (*.xsd) kommt, sondern auf dem althergebrachten Weg in einer Dokumentation der Datenschnittstelle vermerkt wird. Warum ich auf dieses Problem eingehe, wird spätestens dann deutlich, wenn Sie in Delphi über dem Menüpunkt Tools | XML-Mapper das XML-Umwandlungs-Tool starten und die Beispieldatei Rohdaten.xml öffnen (Abb. 1). Dieses Tool kann nur schätzen, welche Eigenschaften die vorgefundenen Datensatzspalten haben sollen. In meinem Beispiel ändere ich also von Hand den Datentyp von Feld1 von String auf Integer und korrigiere bei dieser Gelegenheit auch den Wert der Eigenschaft Wert erforderlich. Die beiden anderen Spalten behalten ihren vorbelegten Datentyp String, nur die Eigenschaft Maximale Länge korrigiere ich von Hand auf den Wert 15 beziehungsweise 30. ![]() Abb. 1: Die Datenstruktur wird von Hand korrigiert Mit einem Doppelklick auf die einzelnen Feld-Einträge im dem linken TreeView wähle ich nun alle Knoten aus - das Tool zeigt die ausgewählten Elemente in der Tabellendarstellung an. Über den Menüpunkt Erzeugen | Datenpaket aus XML wandele ich nun die XML-Daten in eine Datenmenge um, die in einer TClientDataSet-Instanz nutzbar ist. Danach ist auch der Button Umwandlung erzeugen und testen zugänglich - ein beherzter Mausklick auf diesen Button zeigt das ermutigende Ergebnis an (Abb. 2). ![]() Abb. 2: Aus XML mach TClientDataSet-Daten Damit ich aber nicht jedes Mal die gleichen Arbeitsschritte durchführen muss, wenn der Kunde eine neue XML-Datei abliefert, speichere ich über dem Menüpunkt Datei | Umwandlung diese Transformations-Schritte in der Datei XML2CDS.xtr ab. Ich habe aber später vor, die vom Kunden erhaltenen XML-Daten in einem TClientDataSet zu ändern, sodass ich auch die Gegenrichtung benötigte, um die aktuellen TClientDataSet-Daten wieder in das XML-Format zu bringen. Ich schalte daher im XML-Umwandlungs-Tool den Radiobutton von der Einstellung XML in Datenpaket auf die Einstellung Datenpaket in XML um. Wenn ich nun den Button Umwandlung erzeugen und testen anklicke, zeigt das Fenster den TClientDataSet-Inhalt als XML-Dokument an. Also funktioniert auch die Gegenrichtigung, sodass ich diesen Transformations-Schritt in der Datei CDS2XML.xtr abspeichere. Der Transformer Jetzt fehlt noch das Programm, das die vom Kunden erhaltenen XML-Daten auswerten, modifizieren und im gleichen XML-Datenformat speichern soll. Von der Komponenten-Palette ziehe ich dazu die Komponente TXMLTransformProvider auf das Formular. Wenn das Programm gestartet wird, initialisiere ich die Eigenschaften TransformRead und TransformWrite mit den beiden vorhin gespeicherten Transformations-Dateien: procedure TForm1.FormCreate(Sender: TObject);Wenn ich nun über den Datei öffnen-Dialog die XML-Datei Rohdaten.xml auswähle, kann ich diese Datei der TXMLTransformProvider-Eigenschaft XMLDataFile zuordnen. Außerdem wird diese Komponente auch mit der TClientDataSet-Instanz verbunden, dazu greife ich auf die Eigenschaft ProviderName zurück. Wird dann das TClientDataSet geöffnet, nimmt das Programm hinter den Kulissen die notwendige Umwandlung automatisch vor - die Datensätze aus der XML-Datei Rohdaten.xml sind im TDBGrid sichtbar und können dort weiterverarbeitet werden (Abb. 3). procedure TForm1.ActionImportExecute(Sender: TObject); ![]() Abb. 3: Die Daten werden wie gewohnt verarbeitet Das Speichern aller im TDBGrid vorgenommenen Änderungen ist mit einer einzigen Programmzeile erledigt. Der Aufruf der TClientDataSet-Methode ApplyUpdates reicht aus, damit der TXMLTransformProvider den Inhalt der Datensätze zurück in die XML-Datei schreibt: procedure TForm1.ActionExportExecute(Sender: TObject);Für den Fall, dass zwischen Import und Export der XML-Daten mehr Zeit vergeht, ist es effektiver, zwischendurch im nativen XML-Datenformat der TClientDataSet-Komponente zu speichern. Der Aufruf der Methode SaveToFile legt den Inhalt der vorgefundenen Datensätze im sogenannten Borland DataPacket XML-Format ab: procedure TForm1.ActionSaveAsDataPaketExecute(Sender: TObject);C#Builder und TClientDataSet-Daten Das sich der Aufwand mit dem Hantieren mit der TXMLTransformProvider-Komponente auch wirklich lohnt, zeigt das letzte Beispiel. Dort habe ich mit dem Borland C#Builder eine Anwendung zusammengeklickt, die ebenfalls die gleiche XML-Datei lesen und schreiben kann, die ich vorhin beim Delphi-Beispiel verwendet habe. Und wie in Blick in die Implementierung zeigt, benötigt die DataSet-Klasse aus ADO.NET keine vorbereitende Transformation, denn diese Klasse kann direkt mit einem XML-Dokument umgehen. Während die Methode ReadXml für das Einlesen aus der XML-Datei verantwortlich ist, speichert die Methode WriteXml alle in der Zwischenzeit durch das Programm vorgenommene Änderungen am Datenbestand in die XML-Datei zurück (Listing 1).
Listing 1 private DataSet aDS; Das C#Builder-Beispiel könnte man dann sogar noch um den Aufruf der Methode ReadXmlSchema erweitern, um die in einer XSD-Datei vorliegende Strukturbeschreibung automatisch im DataSet wirksam werden zu lassen. TClientDataSet und XML Die TClientDataSet-Komponente von Delphi kann zwar direkt eine XML-Daten lesen und schreiben, allerdings erwartet die Komponente ein spezielles XML-Datenformat, das als Borland DataPacket-Format (alias TClientDataSet-Format) bekannt ist. Immer dann, wenn die Daten im universellen XML-Dokument-Format vorliegen, ist eine Konvertierung notwendig. Sie können sich jederzeit selbst davon überzeugen, indem Sie im Windows-Explorer jeweils die Dateien Rohdaten.xml und BDP_Rohdaten.xml mit einem Doppelklick öffnen. Nur das XML-Dokument Rohdaten.xml wird vom Internet Explorer in der XML-Darstellung angezeigt. |
||
|