Как определить взаимоисключающие атрибуты в XSD?
Сначала фрагмент кода...
<tag name="default" abc="10" def="20> <!-- not valid, abc and def should be mutually exclusive -->
<tag name="default1" abc="10"> <!-- valid -->
<tag name="default2" def="20> <!-- valid -->
То, что я хочу сделать...
Что я могу вложить в свой XSD
так, чтобы @abc
и @def
не могли сосуществовать как атрибуты на одном и том же элементе?
Так что проверка будет неудачной, если они сосуществуют на одном и том же элементе?
2 ответа:
XSD 1.0
Можно сделать с помощью хитрого трюка
xs:key
. Смотрите ответ@Kachna .Обратите внимание, что некоторые Парсеры могут разрешить оба атрибута, если они не завершаются ошибкой для нескольких выбранных значений в
xs:key
. Есть, по крайней мере, один известный случай, когда это происходило в прошлом.XSD 1.1
Можно сделать с помощью
xs:assert
:<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"> <xs:element name="tag"> <xs:complexType> <xs:sequence/> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="abc" use="optional" type="xs:integer"/> <xs:attribute name="def" use="optional" type="xs:integer"/> <xs:assert test="(@abc and not(@def)) or (not(@abc) and @def)"/> </xs:complexType> </xs:element> </xs:schema>
С помощью XSD 1.0 можно использовать элемент
xs:key
.<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="tag"> <xs:complexType> <xs:attribute name="name" type="xs:string" use="required"/> <xs:attribute name="abc" type="xs:integer"/> <xs:attribute name="def" type="xs:integer"/> </xs:complexType> <xs:key name="attributeKey"> <xs:selector xpath="."/> <xs:field xpath="@abc|@def"/> </xs:key> </xs:element>
Редактировать: Если присутствуют оба атрибута (даже с разными значениями), это создает два ключа, поэтому проверка XML завершится неудачей. С другой стороны,
<xs: key>
требует, чтобы для элемента был определен ключ, и поэтому должен присутствовать один из двух атрибутов.Следующий XML-документ недопустим при использовании вышеупомянутого XSD. (Я использую кислород 17.0):
<tag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="stack3.xsd" name="" abc="12" def="13"/>
Ошибка:
cvc-identity-constraint.3: Field "./@abc|./@def" of identity constraint "attributeKey" matches more than one value within the scope of its selector; fields must match unique values