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
Beispielinstanz ohne Namensraum (instance.xml) Rohdatei
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:
Man beachte hier vor allem die Zeilen 15 bis 17, 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.
Beispielinstanz mit Namensraum (instance_namespace.xml) Rohdatei
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.
Falsches Schema mit Zielnamensraum (schema_falsch.xsd) Rohdatei
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:
Richtiges Schema mit Zielnamensraum (schema_richtig.xsd) Rohdatei
Zu beachten sind die Zeilen 4 und 19. 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.