I'm reasonably new to working with XML schemas, so excuse my incompetence if this is more trivial than I myself believe it must be.
I'm trying to create a required attribute that must contain 1 or more white-space-separated string values from a list. The list is the 4 typical HTTP request methods; get
, post
, put
, and delete
.
So valid elements would include:
<rule methods="get" />
<rule methods="get post" />
<rule methods="post put delete" />
Whereas invalid elements would include:
<rule methods="get get" />
<rule methods="foobar post" />
<rule methods="get;post;put" />
I've tried fooling with enumerations and length, but I don't believe I'm understanding what I need to do (or for that matter if it is in fact possible, though it seems as though it should be)
This is where I'm at now, thanks to @tdrury:
<xs:attribute name="methods" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="collapse" />
<xs:pattern value="(?:(?:get|post|put|delete)\s?){1,4}" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
Which works, except for repetition (such as get get
or post post post
) and absent whitespace (such as getpost
or postputdelete
)
Edit:
After playing around with this a bit, I came up with an idea: an enumeration of all possible sequences. Thankfully, this list is (for the time being) fixed to the four usual transport methods, get
, post
, put
, and delete
, so I figured:
<xs:restriction base="xs:string">
<xs:whiteSpace value="collapse" />
<xs:enumeration value="delete" />
<xs:enumeration value="put" />
<xs:enumeration value="put delete" />
<xs:enumeration value="post" />
<xs:enumeration value="post delete" />
<xs:enumeration value="post put" />
<xs:enumeration value="post put delete" />
<xs:enumeration value="get" />
<xs:enumeration value="get delete" />
<xs:enumeration value="get put" />
<xs:enumeration value="get put delete" />
<xs:enumeration value="get post" />
<xs:enumeration value="get post delete" />
<xs:enumeration value="get post put" />
<xs:enumeration value="get post put delete" />
</xs:restriction>
Can anyone see a reason that this would not be a good idea?
The basic problem can be addressed with enumerations as well:
<xs:attribute name="methods" use="required">
<xs:simpleType>
<xs:restriction>
<xs:simpleType>
<xs:list>
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="get"/>
<xs:enumeration value="post"/>
<xs:enumeration value="put"/>
<xs:enumeration value="delete"/>
</xs:restriction>
</xs:simpleType>
</xs:list>
</xs:simpleType>
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
This unfortunately has the same limitation as the <xs:pattern>
solution and cannot validate that each token in the list is unique. It does however address the whitespace issue (getpost
would be rejected).