I have the following XSD structure:
<xs:schema xmlns:ns="http://abc/">
...
<xs:element name="abc">
<xs:complexType>
<xs:sequence>
<xs:element ref="map"/>
</xs:sequence>
</xs:complexType>
</xs:element>
...
<xs:element name="map">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="ns:MapEntryType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="entry">
<xs:selector xpath="entry"/>
<xs:field xpath="key"/>
</xs:unique>
</xs:element>
<xs:complexType name="MapEntryType">
<xs:sequence>
<xs:element name="key" type="xs:string"/>
<xs:element name="value" type="xs:anyType"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
This is doing its job.
The map
element now has to be called something different based on whichever is the wrapper, so the name is sometimes map
, sometimes properties
, sometimes options
, etc.
Therefore I want to genericize the map
element.
I tried doing the following:
map
a xs:complexType
and changing ref
to type
.
xs:unique
not being accepted and failedmap
a xs:complexType
, changing ref
to type
and moving the xs:unique
constraint to the element definitions.
xs:unique
present in the document.Isn't there a way to simply tell that I want a specific structure and it containing unique elements without having to repeat the unique constraint everywhere?
As Petru Gardea said in his answer
Both XSD 1.0 and 1.1 place the identity constraints under an element
So you have to add xs:unique to every element, but if you are using XSD 1.1 you can define only once a complete xs:unique and then in the rest of the elements use xs:unique ref="name". This is not valid for you as you are using XSD 1.0, but I let it here for future XSD 1.1 users that find this good question.
Example (namespaces removed for clarity):
<xs:element name="map">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="MapEntryType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- Only completely defined once -->
<xs:unique name="uniqueEntry">
<xs:selector xpath="entry"/>
<xs:field xpath="key"/>
</xs:unique>
</xs:element>
<xs:element name="hashMap">
<xs:complexType>
<xs:sequence>
<xs:element name="entry" type="MapEntryType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<!-- Referenced here and every other time -->
<xs:unique ref="uniqueEntry"/>
</xs:element>
Short answer, it is not possible. Both XSD 1.0 and 1.1 place the identity constraints under an element; a constraint cannot be globally defined, therefore there is no "reuse" per se, other than that of the enclosing element. Given your scenario (different element names for different needs) it is not possible to reuse.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With