Arbeiten mit DTDs

(Auszug aus "Python & XML" von Christopher A. Jones & Fred L. Drake, Jr.)

Schemata und Validierung spielen eine wichtige Rolle bei der zuverlässigen Kommunikation zwischen Anwendungen. Ein tiefgehendes Verständnis davon, wie man in einem Schema Beziehungen zwischen Dokumenten ausdrückt, ist essentiell, um sie effektiv zu nutzen. In diesem Abschnitt konzentrieren wir uns auf DTDs, aber die hier vorgestellten Konzepte gelten für alle Schemasprachen. Hinweise auf Python-Module, die andere Schemasprachen als die DTD-Sprache unterstützen, die in XML 1.0 definiert ist, finden Sie in der Erläuterung der alternativen Schemasprachen in Dokumenttypen und Schemata.

Die DTD ist in der internen DTD-Teilmenge, der externen DTD-Teilmenge oder einer Kombination von beiden dargestellt. Wie der Name angibt, befindet sich die interne Teilmenge in der XML-Dokumentinstanz selbst, während die externe Teilmenge dort als Link gespeichert ist, der dem Parser sagt, wo er die DTD findet.

Das Paket xmlproc ist ein validierender Parser für Python. Zum gegenwärtigen Zeitpunkt ist es der einzige für Python verfügbare validierende Parser, der auch in Python implementiert ist. Wenn Sie das PyXML-Paket installiert haben, wovon wir in diesem Buch überall ausgehen, verfügen Sie bereits über xmlproc und können es schon in Ihren Programmen benutzen. Das xmlproc-Paket kann aus dem Paket xml.parsers importiert werden:

 >>> from xml.parsers import xmlproc 

Validieren mit der internen DTD-Teilmenge

Wenn Sie schon eine Weile mit XML gearbeitet haben, können Sie sehr wahrscheinlich die Grundsyntax von DTDs schon dadurch verstehen, daß Sie ein paar Beispiele dafür sehen. Das xmlproc-Paket bietet ein Kommandozeilen-Werkzeug namens xvcmd.py. Dieses einfache Modul testet Dokumente auf Gültigkeit hinsichtlich ihrer DTDs. Sie können xvcmd.py benutzen, um einige einfache DTDs auszuprobieren, externe wie interne. Vergewissern Sie sich, daß xvcmd.py in Ihrem Pfad vorkommt (normalerweise direkt unter Ihrem PyXML-Installationsverzeichnis in xmldoc/demo/xmlproc/xvcmd.py).

Hier ist ein kleines XML-Dokument namens product.xml, das eine interne DTD-Teilmenge hat. Zu Illustrationszwecken implementiert das Dokument die DTD nicht gewissenhaft. Sie werden das beim einfachen Betrachten des Codes vielleicht nicht sofort feststellen; daher ist es gut, daß wir xvcmd.py zur Hand haben, um die Gültigkeit zu überprüfen.

Beispiel: product.xml mit einem inkorrekten product-Element

<?xml version="1.0"?>         
<!DOCTYPE product [
         <!ELEMENT name (#PCDATA)>
         <!ELEMENT price (#PCDATA)>
         <!ELEMENT product (name, price)>
]>
<product>
         <name>Bean Crusher</name>
</product>

Probieren Sie xvcmd.py (den Validierer) auf der Kommandozeile aus:

C:\>python c:\python20\xmldoc\demo\xmlproc\xvcmd.py product.xml
xmlproc version 0.70

Parsing 'product.xml'
E:product.xml:9:11: Element 'product' ended, but not finished

Parse complete, 1 error(s) and 0 warning(s)

Wie erwartet, tritt ein Fehler auf. Das Problem besteht darin, daß wir in der DTD explizit das Inhaltsmodell für ein product-Element angeben. Dort steht, daß es genau ein name-Element und ein price-Element enthalten muß:

 <!ELEMENT product (name, price)> 

Außerdem gibt die DTD an, daß jedes dieser Elemente (price und name) nur Zeichendaten enthalten darf, wie in den beiden folgenden Elementdeklarationen gezeigt:

<!ELEMENT name (#PCDATA)>
<!ELEMENT price (#PCDATA)>

Wir können das Problem in Ihrem XML korrigieren, wie in Beispiel product.xml mit einem inkorrekten product-Element gezeigt. Das product-Element braucht ein price-Element darin, und dieses price-Element kann nur Zeichendaten enthalten. Ändern wir also das Dokument products.xml im folgenden Beispiel wie folgt, indem wir ein price-Element ergänzen:

<?xml version="1.0"?>       
<!DOCTYPE product [
       <!ELEMENT name (#PCDATA)>
       <!ELEMENT price (#PCDATA)>
       <!ELEMENT product (name, price)>
]>
<product>
       <name>Bean Crusher</name>
       <price>3.95</price>
</product>

Gehen Sie nun zur Kommandozeile zurück, um den Validierer xvcmd.py erneut auszuprobieren:

C:\>python c:\python20\xmldoc\demo\xmlproc\xvcmd.py product2.xml
xmlproc version 0.70

Parsing 'product.xml'

Parse complete, 0 error(s) and 0 warning(s)

Nun funktioniert das obige Beispiel product.xml mit einem inkorrekten product-Element ohne Probleme, weil die XML-Dokumentinstanz konform mit der DTD ist. Die DTD unterwirft das Inhaltsmodell von einfachen XML-Konstrukten (Elemente, Attribute und Zeichendaten), die in allen XML-Dokumenten erlaubt sind, einer strengen Kontrolle.

Validieren mit einer externen DTD-Teilmenge

Wir haben uns eine interne DTD-Teilmenge angesehen. Untersuchen wir nun eine externe DTD-Teilmenge. Normalerweise wird die DTD extern gespeichert, wenn sie auf viele Dokumentinstanzen angewendet wird. Dadurch, daß die DTD extern vorliegt, können Sie eine DTD verwalten, die auf viele Dokumente angewendet werden kann. Wenn Sie Ihre DTD im Dokument speichern, braucht jede Dokumentinstanz ihre eigene Kopie. Bei einer großen Ansammlung von Dokumentinstanzen ist es schwierig, eine interne DTD zuverlässig zu verwalten. Eine externe DTD ist in diesen Fällen die bessere Idee. Importieren Sie die DTD in das Dokument, wie im folgenden Beispiel gezeigt.

Beispiel: order.xml mit einer externen DTD

<?xml version="1.0"?>
<!DOCTYPE order SYSTEM "order.dtd">
<order>       
     <customer_name>eDonkey Enterprises</customer_name>
     <sku>343-3940938</sku>
     <qty>4</qty>
     <unit_price>39.95</unit_price>
     <product_name>eDonkey Feed Bags</product_name>
</order>

Beachten Sie, daß es keine interne DTD-Teilmenge gibt. Die Datei order.dtd enthält den Dokumenttyp. Sie wird im nächsten Beispiel gezeigt:

Beispiel: order.dtd

<!ELEMENT customer_name (#PCDATA)>
<!ELEMENT sku (#PCDATA)>
<!ELEMENT qty (#PCDATA)>
<!ELEMENT unit_price (#PCDATA)>
<!ELEMENT product_name (#PCDATA)>       
<!ELEMENT order (customer_name,
       sku,
       qty,
       unit_price,
       product_name)>

Die genaue Syntax von Elementtyp-Deklarationen wird im nächsten Abschnitt behandelt. An dieser Stelle genügt es, die allgemeine Zusammensetzung der DTD zu erklären. Im obigen Beispiel order.dtd werden fünf XML-Elemente erzeugt, jedes mit einem Zeichendaten-Inhaltsmodell. Ein sechstes Element namens order wird erzeugt, nimmt aber genau eines der anderen Elemente in seinem Inhaltsmodell auf. Jedes gültige Dokument, das diese DTD benutzt, muß diese Struktur haben. Sie können das neue Dokument und die neue DTD testen, indem Sie xvcmd.py wie hier gezeigt ausführen:

C:\>python c:\python20\xmldoc\demo\xmlproc\xvcmd.py order.xml
xmlproc version 0.70

Parsing 'order.xml'

Parse complete, 0 error(s) and 0 warning(s)

Das Dokument order.xml ist gültig. Wenn Sie das Dokument beliebig verändern, wird es ungültig. Modifizieren wir unser Dokument order.xml so, daß es wie das folgende aussieht, indem wir die Elemente qty und product_name löschen. Das garantiert, daß das Dokument bei einer Validierung ungültig wird:

<?xml version="1.0"?>
<!DOCTYPE order SYSTEM "order.dtd">
<order>
  <customer_name>eDonkey Enterprises</customer_name>
  <sku>343-3940938</sku>
  <unit_price>39.95</unit_price>
</order>

In diesem Fall beschwert sich der Parser über die neue Dokumentstruktur:

C:\>python c:\python20\xmldoc\demo\xmlproc\xvcmd.py order.xml
xmlproc version 0.70

Parsing 'badorder.xml'
E:badorder.xml:6:14: Element 'unit_price' not allowed here
E:badorder.xml:7:9: Element 'order' ended, but not finished

Parse complete, 2 error(s) and 0 warning(s)

Im allgemeinen ist es eine gute Idee, die DTD extern unterzubringen. Es ist wesentlich flexibler, da es gestattet, mehrere Dokumentinstanzen mit einer einzigen DTD zu vergleichen. Eine DTD ist z. B. wesentlich besser, wenn Ihre Dokumente im Internet veröffentlicht werden. Sie können leicht XML-Dokumentinstanzen über die ganze Welt verstreut haben, aber wenn ihre Dokumenttyp-Deklarationen auf die URL einer gültigen DTD zeigen, können diese immer noch validiert werden. Die DTD mit einer URL anzugeben ermöglicht es Ihnen, eine einzige Kopie einer DTD online zu halten.

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema Python & XML bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2002 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "Python & XML" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O’Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de