Optional key in XSD -
i've created key
/keyref
on root element in order create document-wide uniqueness based on specified element.
therefore, via .//foo/@name
every occurrence of @name
across instances of foo
must unique; likewise .//bar/@name
. seems working fine. these referenced .//foo-ref/@name-ref
, .//bar-ref/@name-ref
respectively, defined @ root node.
however, i've gathered 1 cannot create optional key, , presenting bit of problem. semantically, nature of conforming documents, key not required on every single instance of foo
or bar
. instances of foo-ref/@name-ref
need target existing foo/@name
, isn't semantically invalid foo
without @name
.
is there work-around this? don't idea of consumers having define key every single element, when reasonably handful need them.
here's example schema (of course, i'm not deploying foobar
schema, structure identical; testing schema i've been toying with)
<xs:schema elementformdefault="qualified" xmlns:xs="http://www.w3.org/2001/xmlschema"> <xs:complextype name="ref"> <xs:attribute name="name-ref" type="xs:string" use="required" /> </xs:complextype> <xs:complextype name="obj"> <xs:attribute name="name" type="xs:string" use="optional" /> </xs:complextype> <xs:complextype name="foo"> <xs:complexcontent> <xs:extension base="obj"> <xs:sequence> <xs:choice maxoccurs="unbounded"> <xs:element name="foo" type="foo" /> <xs:element name="bar" type="bar" /> <xs:element name="foo-ref" type="foo-ref" /> <xs:element name="bar-ref" type="bar-ref" /> </xs:choice> </xs:sequence> </xs:extension> </xs:complexcontent> </xs:complextype> <xs:complextype name="foo-ref"> <xs:complexcontent> <xs:extension base="ref" /> </xs:complexcontent> </xs:complextype> <xs:complextype name="bar"> <xs:complexcontent> <xs:extension base="obj"> <xs:sequence> <xs:choice maxoccurs="unbounded"> <xs:element name="bar" type="bar" /> <xs:element name="qux" type="qux" /> <xs:element name="bar-ref" type="bar-ref" /> </xs:choice> </xs:sequence> </xs:extension> </xs:complexcontent> </xs:complextype> <xs:complextype name="bar-ref"> <xs:complexcontent> <xs:extension base="ref" /> </xs:complexcontent> </xs:complextype> <xs:complextype name="qux"> <xs:simplecontent> <xs:extension base="xs:string" /> </xs:simplecontent> </xs:complextype> <xs:element name="root"> <xs:complextype> <xs:sequence> <xs:element name="foo" type="foo" maxoccurs="unbounded" /> </xs:sequence> </xs:complextype> <xs:key name="foo"> <xs:selector xpath=".//foo" /> <xs:field xpath="@name" /> </xs:key> <xs:key name="bar"> <xs:selector xpath=".//bar" /> <xs:field xpath="@name" /> </xs:key> <xs:keyref name="foo-ref" refer="foo"> <xs:selector xpath=".//foo-ref" /> <xs:field xpath="@name-ref" /> </xs:keyref> <xs:keyref name="bar-ref" refer="bar"> <xs:selector xpath=".//bar-ref" /> <xs:field xpath="@name-ref" /> </xs:keyref> </xs:element> </xs:schema>
addendum
just following revisions @petrugardea. unique
can referenced keyref
, knew? (not me apparently)
<xs:element name="root"> <xs:complextype> <xs:sequence> <xs:element name="foo" type="foo" maxoccurs="unbounded" /> </xs:sequence> </xs:complextype> <xs:keyref name="foo-ref" refer="foo"> <xs:selector xpath=".//foo-ref" /> <xs:field xpath="@name-ref" /> </xs:keyref> <xs:keyref name="bar-ref" refer="bar"> <xs:selector xpath=".//bar-ref" /> <xs:field xpath="@name-ref" /> </xs:keyref> <!-- use of xs:unique here, in lieu of xs:key allows nullable "keys", retaining referential integrity above defined keyrefs. awesome possum. --> <xs:unique name="foo"> <xs:selector xpath=".//foo" /> <xs:field xpath="@name" /> </xs:unique> <xs:unique name="bar"> <xs:selector xpath=".//bar" /> <xs:field xpath="@name" /> </xs:unique> </xs:element>
use xsd:unique; unlike key, matched value either unique or nil (nil or not present).
example:
<?xml version="1.0" encoding="utf-8" ?> <!-- xml schema generated qtassistant/xsd module (http://www.paschidev.com) --> <xsd:schema xmlns:xsd="http://www.w3.org/2001/xmlschema"> <xsd:element name="root"> <xsd:complextype> <xsd:sequence> <xsd:element name="uk" maxoccurs="unbounded"> <xsd:complextype> <xsd:attribute name="name" type="xsd:string"/> </xsd:complextype> </xsd:element> <xsd:element name="fk" maxoccurs="unbounded"> <xsd:complextype> <xsd:attribute name="name" type="xsd:string"/> </xsd:complextype> </xsd:element> </xsd:sequence> </xsd:complextype> <xsd:unique name="uq"> <xsd:selector xpath="uk"/> <xsd:field xpath="@name"/> </xsd:unique> <xsd:keyref name="fk" refer="uq"> <xsd:selector xpath="fk"/> <xsd:field xpath="@name"/> </xsd:keyref> </xsd:element> </xsd:schema>
sample (valid) xml:
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- sample xml generated qtassistant (http://www.paschidev.com) --> <root xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <uk name="name1"/> <uk /> <fk/> <fk name="name1"/> </root>
Comments
Post a Comment