Reputation: 3502
I'm trying to create an XSD for an existing XML document. I really cannot change the XML, so I need to make the XSD fit it (I know this is somewhat backwards).
In the XML, there is an element called a Group. This element has one or more Features. There are about 40 valid feature names. So I chose to model them as an Enum. The enum looks like this:
<xs:simpleType name="FeatureNamesEnumType">
<xs:restriction base="xs:normalizedString">
<xs:enumeration value="Feature1"/>
<xs:enumeration value="Feature2"/>
<xs:enumeration value="Feature3"/>
</xs:restriction>
</xs:simpleType>
Then, for the group I have the following:
<xs:complexType name="groupType">
<xs:attribute type="FeatureNamesEnumType" name="features" use="required"/>
</xs:complexType>
The issue I keep running into is that in the XML file, an attribute may be set to a comma separated list of features. For example:
<group name="Group1"
features="Feature1,Feature2"
</group>
This doesn't validate against the XSD, because this comma separated list is no in the enumeration.
I know that it would be best to make a group contain a sequence of features, but that is not an option since I cannot change the XML file.
My goal is to cause validation to fail if the features don't match the enum values. So for example I would want the following to be invalid:
<group name="Group1"
features="Feature1,Featur2"
</group>
The misspelling should cause this to be invalid. Is there a way in my XSD to indicate that the features attribute on Group accepts a comma separated list made up of only valid enumeration values?
Upvotes: 2
Views: 2965
Reputation: 159
Using a regular expression with xs:pattern
you could completely validate the value of the features
attribute in the XSD. Depending on your needs something like <xs:simpleType><xs:restriction base="xs:token"><xs:pattern value="(Feature1|Feature2|Feature3)(,(Feature1|Feature2|Feature3))*"/></xs:restriction></xs:simpleType>
.
Upvotes: 2
Reputation: 21638
Just by itself, XSD 1.0 cannot be used to define the constraints you need. If you could pre- or post-process these fields to replace the comma with a whitespace, then you could define an xsd:list of your FeatureNamesEnumType
.
The right approach depends on your platform. For e.g., if on .NET, I would define these fields as strings, maybe constrainted by a xsd:pattern; then I would manually validate each field's value against the simple type defined as the xsd:list above - which is a very simple thing to do in .NET. How you would get to these fields efficiently, would depend on your processing model...
Upvotes: 3