Чтобы атрибуты зависели от содержимого других атрибутов, вам потребуется XSD 1.1 (или какое-нибудь расширение XSD 1.0, например Schematron). В XSD 1.1 вы можете использовать утверждение xs:assert
, где вы объявляете правила для сложного типа с помощью XPath.
Чтобы проверить этот экземпляр:
<modes>
<A mode="ENABLE" attr1="abc" attr2="xyz" />
<A mode="DISABLE" attr3="abc" attr4="xyz" />
</modes>
Вы можете использовать XSD, как показано ниже:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
<xs:element name="modes">
<xs:complexType>
<xs:sequence>
<xs:element ref="A" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:attributeGroup name="enabled-attributes">
<xs:attribute name="attr1" type="xs:string" use="optional"/>
<xs:attribute name="attr2" type="xs:string" use="optional"/>
</xs:attributeGroup>
<xs:attributeGroup name="disabled-attributes">
<xs:attribute name="attr3" type="xs:string" use="optional"/>
<xs:attribute name="attr4" type="xs:string" use="optional"/>
</xs:attributeGroup>
<xs:element name="A">
<xs:complexType>
<xs:attributeGroup ref="disabled-attributes"/>
<xs:attributeGroup ref="enabled-attributes"/>
<xs:attribute name="mode" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="ENABLE" />
<xs:enumeration value="DISABLE" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:assert test="(@mode='ENABLE' and @attr1 and @attr2 and not(@attr3) and not(@attr4))
or (@mode='DISABLE' and @attr3 and @attr4 and not(@attr1) and not(@attr2))"/>
</xs:complexType>
</xs:element>
</xs:schema>
Я поместил атрибуты для каждого режима в отдельную группу атрибутов. Ваш атрибут mode
на самом деле не fixed
, но может иметь два значения, поэтому я использовал перечисление, чтобы ограничить его этими двумя значениями.
Строка, для которой требуется XSD 1.1, — это строка xs:assert
. Выражение XPath вычисляется относительно элементов сложного типа. Если выражение истинно, оно будет проверено.
В противном случае проверка не будет выполнена. Оба этих узла A
не пройдут проверку:
<modes>
<A mode="DISABLE" attr1="fgs" attr4="hjs" />
<A mode="ENABLE" attr3="fgs" attr4="hjs" />
</modes>
Обновление: я добавил пункты not()
выше, поскольку, как вы заметили, утверждение было неполным. Теперь это подтверждается как false:
<A mode="DISABLE" attr1="fgs" attr2="hjs" attr3="fgs" attr4="fgs"/>
Вы также можете использовать другие критерии (это подмножество XPath), такие как количество атрибутов, например, если у вас много атрибутов и вы хотите избежать множества предложений not()
, которые вы можете использовать:
@mode='ENABLE' and @attr1 and @attr2 and count(@*) = 3
это ограничит общее количество атрибутов до 3.
person
helderdarocha
schedule
22.04.2014