#xml #validation #list #xsd
#xml #проверка #Список #xsd
Вопрос:
У меня есть XML-файл и соответствующий XSD-файл.
В файле XSD я определяю атрибут list, в котором элементы в списке являются частью перечисления.
Вот пример того, что я делаю.
<xs:simpleType name="Colors">
<xs:list itemType="ColorEnum"/>
</xs:simpleType>
<xs:simpleType name="ColorEnum">
<xs:restriction base="xs:token">
<xs:enumeration value="Red"/>
<xs:enumeration value="Blue"/>
<xs:enumeration value="Green"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Color">
<xs:complexType>
<xs:attribute name="ColorList" type="Colors" />
</xs:complexType>
</xs:element>
XML будет выглядеть примерно так:
<Color ColorList="Red Blue Green"></Color>
Есть ли какой-либо способ убедиться, что элементы в списке уникальны? Например, есть ли какой-либо способ предотвратить попадание Red в этот список дважды?
Ответ №1:
Я думаю, что единственный способ — использовать xsd:pattern
. Вы хотите:
<xs:simpleType name="ColorEnum">
<xs:restriction base="xs:string">
<xs:pattern value="(Red){0,1}s(Blue){0,1}s(Green){0,1}"/>
</xs:restriction>
</xs:simpleType>
Это также должно обеспечить соблюдение порядка. Я имею в виду, что вы не можете предоставить последовательность «Синий Зеленый красный». В любом случае это должно быть отправной точкой.
РЕДАКТИРОВАТЬ очень неприятно:
<xs:simpleType name="ColorEnum">
<xs:restriction base="xs:string">
<xs:pattern value="((Red)?s(Blue)?s(Green)?)|((Red)?s(Green)?s(Blue)?)|((Green)?s(Blue)?s(Red)?)|((Green)?s(Red)?s(Blue)?)|((Blue)?s(Green)?s(Red)?)|((Blue)?s(Red)?s(Green)?)"/>
</xs:restriction>
</xs:simpleType>
Редактировать
Количество комбинаций задается факториалом общего количества элементов, которые вы используете в последовательности. Я надеюсь, что тогда вы не превысите трех элементов 🙂
Ответ №2:
В XSD 1.1 (доступен сейчас в Xerces и Saxon) вы можете сделать
<xs:assertion test="count(tokenize($value, 's ')) =
count(distinct-values(tokenize($value, 's ')))"/>
Комментарии:
1. 1 Приятно знать. @webe0316: смотрите ibm.com/developerworks/library/x-xml11pt2
Ответ №3:
Боюсь, что это невозможно с xs:enumeration
, вы можете использовать какое-нибудь неприятное регулярное выражение вроде:
<xs:simpleType name="ColorEnum">
<xs:restriction base="xs:string">
<xs:pattern value="(Red)?( Blue)?( Green)?"/>
</xs:restriction>
</xs:simpleType>
В этом случае порядок элементов фиксирован.