Динамический атрибут в XSD-схеме элемента

Можно добавить динамический атрибут в <element>, например, у меня есть элемент <A>, у него есть фиксированное имя атрибута mode

<A mode="ENABLE"> <!-- ENABLE or DISABLE-->

if mode is enable then it will add some more dynamic attribute in element `<A>`

like

<A mode="ENABLE" attr1="abc" attr2="xyz">

if mode is disable then it will like this .

<A mode="DISABLE" attr3="abc" attr4="xyz">

Это означает, что атрибут mode фиксирован, а attr1,attr2,attr3 and attr4 зависит от значений атрибута mode.

mode - Фиксированный атрибут.

attr1,attr2,attr3 and attr4 — динамический атрибут зависит от значения mode

Пожалуйста, дайте мне подходящий пример.


person Lavekush Agrawal    schedule 22.04.2014    source источник


Ответы (1)


Чтобы атрибуты зависели от содержимого других атрибутов, вам потребуется 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
comment
Это также подтверждается схемой: <A mode="DISABLE" attr1="fgs" attr2="hjs" attr3="fgs" attr4="fgs"/>, поэтому она кажется частично правильной. Спасибо за вашу поддержку, не могли бы вы еще раз улучшить этот ответ. - person Lavekush Agrawal; 23.04.2014