Hallo,
Tja watt nun?
Du bist meiner Antwort vorgekommen, hätte dir das gleiche gesagt, wie du es nun herausgefunden hast (mehr oder weniger).
Dein key:
> <xsd:key name="myKey">
> <xsd:selector xpath="a"/>
> <xsd:field xpath="b/@name"/>
> <xsd:field xpath="@name"/>
> </xsd:key>
funktioniert nicht, denn bei einer Struktur wie:
<a name="s">
<b name="v">..</b>
<b name="w">..</b>
<b name="x">..</b>
</a>
<a name="t">
<b name="x">..</b>
<b name="y">..</b>
<b name="z">..</b>
</a>
<a name="u">
<b name="x">..</b>
<b name="y">..</b>
<b name="z">..</b>
</a>
produziert b/@name mehrere Treffer.
Das kann man noch verhindern:
<xs:element name="root">
<xs:key name="KeyAB1">
<xs:selector xpath="a" />
<xs:field xpath="@name" />
</xs:key>
</xs:element>
<xs:element name="a">
<xs:key name="KeyAB2">
<xs:selector xpath="b"></xs:selector>
<xs:field xpath="@name"></xs:field>
</xs:key>
</xs:element>
jetzt muss man <c> noch referenzieren:
<xs:element name="root">
<xs:key name="KeyAB1">
<xs:selector xpath="a" />
<xs:field xpath="@name" />
</xs:key>
<xs:keyref refer="KeyAB1" name="RefKeyC">
<xs:selector xpath="c" />
<xs:field xpath="@context" />
</xs:keyref>
</xs:element>
das erlaubt abre noch immer z.B:
<c context="t">...
<c context="t">...
also muss man Eindeutigkeitsbeschränkung für <c> definieren (keyref impliziert nicht Eindeutigkeit) :
<xs:element name="root">
<xs:key name="KeyAB1">
<xs:selector xpath="a" />
<xs:field xpath="@name" />
</xs:key>
<xs:unique name="C">
<xs:selector xpath="c" />
<xs:field xpath="@context" />
</xs:unique>
<xs:keyref refer="KeyAB1" name="RefKeyC">
<xs:selector xpath="c" />
<xs:field xpath="@context" />
</xs:keyref>
</xs:element>
Man kann/soll ebenfalls noch für <d> eine Eindeutigkeitsbeschränkung machen.
<xs:element name="c">
<xs:unique name="D">
<xs:selector xpath="d" />
<xs:field xpath="@id" />
</xs:unique>
</xs:element>
Die Schwierigkeit ist jetzt, wie referneziert man ein bestimmtes <b> von einem bestimmten <a> ausgehend in <c>/<d>.
Und das geht eben nicht. Man kann noch eine Referenz setzen:
<xs:element name="root">
<xs:key name="KeyAB1">
<xs:selector xpath="a" />
<xs:field xpath="@name" />
</xs:key>
<xs:unique name="C">
<xs:selector xpath="c" />
<xs:field xpath="@context" />
</xs:unique>
<xs:keyref refer="KeyAB1" name="RefKeyC">
<xs:selector xpath="c" />
<xs:field xpath="@context" />
</xs:keyref>
<xs:keyref refer="KeyAB2" name="RefKeyD">
<xs:selector xpath="c/d" />
<xs:field xpath="@id" />
</xs:keyref>
</xs:element>
ABER: weil keyref eben keine Eindeutigkeit impliziert, können hier beliebige <b>-werte referenziert werden, sie müssen nur vorhanden sein. Dadurch ist z.B. so etwas möglich:
<a name="s">
<b name="v">..</b>
<b name="w">..</b>
<b name="x">..</b>
</a>
<a name="u">
<b name="x">..</b>
<b name="y">..</b>
<b name="z">..</b>
</a>
<c context="s">
<d id="z">..</d> <---- falsche Referenz, ist aber "gültig"
<d id="x">..</d>
</c>
<c context="u">
<d id="x">..</d>
<d id="y">..</d>
</c>
Was tun? Das XML anderes designen?
Grüße
Thomas
Hier nochmal das Schema insgesamt:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="a"/>
<xs:element maxOccurs="unbounded" ref="c" />
</xs:sequence>
</xs:complexType>
<xs:key name="KeyAB1">
<xs:selector xpath="a" />
<xs:field xpath="@name" />
</xs:key>
<xs:unique name="C">
<xs:selector xpath="c" />
<xs:field xpath="@context" />
</xs:unique>
<xs:keyref refer="KeyAB1" name="RefKeyC">
<xs:selector xpath="c" />
<xs:field xpath="@context" />
</xs:keyref>
<xs:keyref refer="KeyAB2" name="RefKeyD">
<xs:selector xpath="c/d" />
<xs:field xpath="@id" />
</xs:keyref>
</xs:element>
<xs:element name="a">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="b"/>
</xs:sequence>
<xs:attribute name="name" use="required" type="xs:NCName"/>
</xs:complexType>
<xs:key name="KeyAB2">
<xs:selector xpath="b"></xs:selector>
<xs:field xpath="@name"></xs:field>
</xs:key>
</xs:element>
<xs:element name="b">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:NMTOKEN">
<xs:attribute name="name" use="required" type="xs:NCName"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="c">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="d"/>
</xs:sequence>
<xs:attribute name="context" use="required" type="xs:NCName"/>
</xs:complexType>
<xs:unique name="D">
<xs:selector xpath="d" />
<xs:field xpath="@id" />
</xs:unique>
</xs:element>
<xs:element name="d">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:NMTOKEN">
<xs:attribute name="id" use="required" type="xs:NCName"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>