--- layout: post title: "XML Schema, Keys und Namespaces" date: 2012-05-07 18:03 comments: true categories: XML description: "Probleme mit XML Schema, Keys und Namespaces" keywords: "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.