Code aus XML generieren lassen von Nocturne zum Thema Code To Joy - Mi, 27.06.2007

In einem meiner aktuellen Projekte geht es darum, Produkt-Kataloge im PDF-Format automatisch mit den Daten aus einer Datenbank zu erstellen. Die Kataloge sollen direkt als Druckvorstufe herhalten, wovon dann mehrere 1000 Stück gedruckt werden.

Um möglichst flexibel auf zukünftige Änderungen reagieren und um mehrere Katalog-Formate bedienen zu können, überlegte ich mir eine Art Template-System: Meine Anwendung lädt ein Katalog-Format als XML-Schema und ruft dann die zugehörigen Daten aus der Datenbank ab. Die XML-Datei spezifiziert dabei das Layout für jede Seite im Katalog. Bereits nach kurzer Zeit stellte sich heraus, dass XML für solche Aufgaben quasi prädestiniert ist, denn es erlaubt die exakte serialisierte Abbildung eines Katalogs.

Während die erste XML-Datei schnell geschrieben war, ging es nun darum die darin enthaltenen Informationen in meiner Anwendung zu verwenden ... eine Schnittstelle musste gefunden werden.
Da XML ja im Grunde Plaintext ist, war der erste Gedanke natürlich:

  1. Datei öffnen
  2. Stream einlesen
  3. Stream als String speichern und durchsuchen
Jedoch ist das die denkbar ungünstigste, aufwendigste und zugleich unnötigste Möglichkeit. Denn .Net bietet in Sachen XML viel mehr als das! Zunächst wurde ich auf den Namespace System.Xml aufmerksam. Die Klasse XMLReader darin, arbeitet prinzipiell nach dem selben Schema, "versteht" allerdings den Inhalt. Dadurch ist es möglich direkt Elemente und deren Attribute auszulesen.

Auf diese Art und Weise wäre nun nur noch eine Schnittstellen-Klasse nötig gewesen, die Objekte und deren Eigenschaften auf Grundlage der eingelesenen Informationen definiert.
Glücklicherweise fand ich eine noch wesentlich einfachere und zugleich verblüffendere Möglichkeit: ich lasse mir genau diese Schnittstellen-Klasse automatisch generieren und zwar so:

  1. XML-Datei in Visual Studio öffnen
  2. Im Menü 'XML' den Punkt 'Schema erstellen' wählen
  3. Erstelltes Schema speichern und mittels XSD-Tool die Klassenstruktur generieren
Das im Punkt 2 erstellte Schema ist eine XSD-Datei, die aus den XML-Daten eine Struktur mit Datentypen generiert, die grafisch dargestellt werden kann. Umso vollständiger die XML-Daten, desto exakter ist das generierte Schema. Anschließend wird dieses Schema mit dem "XML Schema Definition Tool" [1] von Microsoft in eine Klassenstruktur überführt:
If you specify an XML schema file (.xsd extension), Xsd.exe generates source code for runtime objects that correspond to the XML schema.
Auch den umgekehrten Weg beherrscht das kleine Tool und noch einiges mehr. Ich war jedoch sehr verblüfft, denn wenn ich diese Schnittstelle selbst hätte schreiben müssen, wäre dafür mit Sicherheit ein Tag Arbeit nötig gewesen. So brauchte ich nur die Datentypen im generierten XSD-Schema zu prüfen und ggf. ändern und den Rest erledigte mir eine kurzerhand selbst geschriebene Batch-Datei, um die Konsolen-Parameter von xsd.exe nicht stets neu festlegen zu müssen.

Das funktionierte bei mir alles erstaunlich gut und zuverlässig. Elemente die in der XML-Datei Unterelemente besitzen, werden in der Klasse automatisch vom Typ Aufzählung abgeleitet, sodass ein indexbasierter Zugriff auf alle Unterobjekte dieses Typs möglich ist. Das Einlesen eines Katalog-Templates war dann kein Problem mehr. Das XSD-Tool bietet es an, eine Klassenstruktur mit öffentlichen Eigenschaften oder Feldern zu generieren oder alternativ ein typisiertes DataSet. Einfacher kann man XML-Daten wohl nicht einlesen und verarbeiten.

[1] XML Schema Definition Tool

Stolperfalle Connection PoolingHilfreiche 404 Fehlerseiten dank Google Widget