Hallo,
Schritt 1 ist also klar, Schritt 2 macht mir eben Sorgen. Wo gebe ich das keyref an? Innerhalb des Elements in dem das Attribut definiert ist oder eine Ebene höher? Woher weiß der, dass genau das Attribut gemeint ist?
Du möchtest eine einfache Prüfung auf Eindeutigkeit. Dabei muss du beachten, dass die Definition dieser Einschränkung dort passiert, wo es gebraucht wird. D.h. der Ausgangspunkt ist das Element unterhalb dessen diese Prüfung stattfinden soll, also z.B.:
<xs:element name="Bestellung">
xs:complexType
...
</xs:complexType>
<xs:unique name="PersonID">
<xs:selector xpath="Person"/>
<xs:field xpath="@PersonID"/>
</xs:unique>
</xs:element>
Damit würdest du bestimmen, dass innerhalb von Bestellung jede Person, die über ihre PersonID identifiziert wird, eindeutig bestimmt sein sollte. D.h. es dürfen keine zwei Kunden mit derselben PersonID innerhalb einer Bestellung auftreten.
Hättest du:
<xs:element name="Bestellungen">
xs:complexType
...
</xs:complexType>
<xs:unique name="PersonID">
<xs:selector xpath="Bestellungen/Person"/>
<xs:field xpath="@PersonID"/>
</xs:unique>
</xs:element>
würde dies dasselbe bedueten.
Ein <xs:selector xpath=".//Person"/> in diesem Konstrukt würde dagegen bedeuteten, dass in Bestellungen jede Person, die über ihre PersonID identifiziert wird, eindeutig bestimmt sein sollte. D.h. es dürfen keine zwei Kunden mit derselben PersonID innerhalb von Bestellungen auftreten.
Das ist also die eine Sache. Damit hättest du die Eindeutigkeit von Person sichergestellt.
Was du mit <xs:keyref name="Person" refer="PersonID"> erreichen möchtest ist mir nicht ganz klar.
Solltest du z.B. eine Struktur wie:
<root>
<Bestellungen>
<Bestellung ... >
...
</Bestellungen>
<Personen>
<Person ...>
...
<Personen>
</root>
haben, und aus einer Bestellung heraus sicherstellen, dass zu einer dort angegebenen Person tatsächlich eine Person aus Personen existiert, solltest du key und keyref verwenden.
Mit key würdest du ebenfalls eine Eindeutigkeitsbeschränkung (oder Identitätsbeschränkung) defineren, mit dem Unterschied, dass alle als Felder (xs:filed) genannte Knoten existieren müssen. Bei unique gilt, falls ein Feld (xs:filed) zwar definiert, aber der Knoten nicht vorhanden ist, wird der Selektor einfach ignoriert. key impliziert Eindeutigkeit, aber unique impliziert keinen key.
Bei obiger Sturktur könntest du ein key im Personen für Person anlegen, dann muss du aber diese im root mit keyref referenzieren, was im Sinne von XML-Schema zulässig ist.
--------------------------
<xs:element name="root">
xs:complexType
<xs:element name="Bestellungen">
xs:complexType
<xs:element name="Bestellung">
xs:complexType
...
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
<xs:element name="Personen">
xs:complexType
<xs:element name="Person">
xs:complexType
...
</xs:complexType>
<xs:key name="PersonID">
<xs:selector xpath="Person"/>
<xs:field xpath="@PersonID"/>
</xs:key>
</xs:element>
</xs:complexType>
</xs:element>
</xs:complexType>
<xs:keyref name="PersonID2" refer="PersonID">
<xs:selector xpath="Bestellungen/Bestellung/Person"/>
<xs:field xpath="@PersonID"/>
</xs:keyref>
</xs:element>
------------------------
Du kannst aber auch einen key im root auf Personen/Person defineren und diese dann in Bestellung für Person referenzieren:
-------------------------------------
<xs:element name="root">
xs:complexType
<xs:element name="Bestellungen">
xs:complexType
<xs:element name="Bestellung">
xs:complexType
...
</xs:complexType>
<xs:keyref name="PersonID2" refer="PersonID">
<xs:selector xpath="Person"/>
<xs:field xpath="@PersonID"/>
</xs:keyref>
</xs:element>
</xs:complexType>
</xs:element>
<xs:element name="Personen">
xs:complexType
<xs:element name="Person">
xs:complexType
...
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
</xs:complexType>
<xs:key name="PersonID">
<xs:selector xpath="Personen/Person"/>
<xs:field xpath="@PersonID"/>
</xs:key>
</xs:element>
--------------------------------------
Grüße
Thomas