Is it possible to specify an equivalent of HTML’s <option selected> in XSD — exactly and only one element has a particular attribute?
For example, given the following example XML fragment:
<foo-list>
<foo/>
<foo bar="bar"/>
<foo/>
</foo-list>
I can write the following XSD to ensure that only one foo has @bar:
<xs:element name="foo-list">
<!-- FOO-LIST contains [1..n] FOO elements -->
<xs:complexType>
<xs:sequence>
<xs:element ref="foo" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- any FOO with @BAR must have unique @BAR -->
<xs:unique name="oneFooBar">
<xs:selector xpath="foo"/>
<xs:field xpath="@bar"/>
</xs:unique>
</xs:element>
<xs:element name="foo">
<xs:complexType>
<!-- FOO has optional @BAR -->
<xs:attribute name="bar">
<xs:simpleType>
<!-- @BAR must = "bar", if specified -->
<xs:restriction base="xs:string">
<xs:enumeration value="bar"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
Assuming everything’s properly qualified, and that my decision to use a solitaire enumeration instead of a pattern is sound:
1) does this schema sensibly mean what I intended? (i.e. there are zero or one <foo bar="bar"/> and zero or more <foo/> in the <foo-list>)
2) is there a way to require that there be exactly one <foo bar="bar"/> ?
1) Yes, it does, in a “weird” workaround-ish way.
2) Not with stock XSD 1.0. Throw in Schematron, and you’re all set. Or move to XSD 1.1 with assertions (which allows you exactly what Schematron does for what you want). The thing is, since you’re not specifying a target platform, XSD 1.1 implementations are hard to come by (Java has a free option in Xerces and paid in Saxon EE) but others, such as .NET have nothing free. A Schematron “compiler” is really just a tranformation of the schema into XSLT; it can be 1.0 or 2.0, which means it can be used to augment a normal XSD 1.0 on virtually any (reasonable) platform.