Как определить взаимоисключающие атрибуты в 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>
Edit:
Если оба атрибута (даже с разными значениями), это создает два ключа, поэтому проверка 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