mpuppe.de-blog-posts/posts/2012-05-07-xml-schema.markdown

2.3 KiB

layout title date comments categories description keywords
post XML Schema, Keys und Namespaces 2012-05-07 18:03 true XML Probleme mit XML Schema, Keys und Namespaces xml schema, keys, namespaces, schlüssel, namensräume

Bei der Erstellung von Schemas mit einem Ziel-Namensraum kann man leicht in eine kleine, facepalm-induzierende Falle tappen, die mich heute einiges an Nerven gekostet hat. Um das Problem zu erläutern sehen wir uns am besten ein Beispiel an.

Ohne Namensraum

{% include_code Beispielinstanz ohne Namensraum 2012-05-07/instance.xml %}

Das Dokument besteht aus einem Wurzelement foo und Kindelementen bar. Die bar-Elemente haben ein Attribut id. Nun wollen wir erzwingen, dass id ein Schlüssel ist. Die Instanz wäre dann nicht valide. Das entsprechende XML-Schema muss dazu etwa so aussehen:

{% include_code Schema ohne Ziel-Namensraum 2012-05-07/schema.xsd lang:xml %}

Man beachte hier vor allem die Zeilen 14 bis 16, in denen festgelegt wird, dass innerhalb des foo-Elements die bar-Elemente eindeutig durch das Schlüssel-Attribut id identifizierbar sein müssen.

Mit Namensraum

Hier folgt eine Beispiel-Instanz, für die http://foo.bar als Namensraum festgelegt wurde.

{% include_code Beispielinstanz mit Namensraum 2012-05-07/instance_namespace.xml %}

Man könnte nun meinen, dass es ausreicht, den Namensraum entsprechend auch im Schema anzugeben. Das wurde im folgenden Beispiel in Zeile 3 und 4 getan.

{% include_code Falsches Schema mit Zielnamensraum 2012-05-07/schema_falsch.xsd lang:xml %}

Das Problem ist aber, dass die Beispiel-Instanz nicht als invalide erkannt wird, sondern klaglos akzeptiert wird. Warum ist das so? Das Problem ist der XPath-Ausdruck in Zeile 17. Damit werden alle bar-Elemente selektiert und sichergestellt, dass diese eine eindeutige id haben. Unser Ziel-Namensraum ist allerdings http://foo.bar. Das heißt wir wollen nicht bar-Elemente selektieren, sondern http://foo.bar:bar-Elemente. Das richtige Schema sieht deshalb so aus:

{% include_code Richtiges Schema mit Zielnamensraum 2012-05-07/schema_richtig.xsd lang:xml %}

Zu beachten sind die Zeilen 4 und 18. In Zeile 4 wird definiert, dass das Kürzel foobar für den Namensraum http://foo.bar steht und in Zeile 18 wird dieses Kürzel verwendet, um den korrekten XPath-Ausdruck zu konstruieren.