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.