Import old blog posts

This commit is contained in:
Martin Puppe 2020-08-08 14:30:21 +02:00
commit 8084c1e15f
23 changed files with 1384 additions and 0 deletions

View file

@ -0,0 +1,37 @@
---
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.