XSD 1.1: использование атрибута только при наличии другого необязательного атрибута

#xml #if-statement #xsd #attributes #conditional-statements

#xml #if-оператор #xsd #условные операторы #утверждать

Вопрос:

Предполагается, что я напишу xsd для простого и небольшого симулятора ресторана. Для этого симулятора у меня есть несколько элементов, которые все считаются едой. Некоторым из них не нужны дополнительные атрибуты, поскольку они готовы к работе. Однако некоторые из этих элементов питания нуждаются в подготовке, а некоторым элементам, которые также нуждаются в подготовке, должно быть разрешено готовить, только если присутствует что-то еще. Для этого им должен быть присвоен атрибут «условие» (см. Пример):

 <food>
   <name>tea</name>
   <preparation>Ready to Go</preparation>
</food>

<food>
   <name>sandwich</name>
   <preparation time="2">Toaster</preparation>
</food>

<food>
   <name>noodles</name>
   <preparation time="5">Cooking-Pot</preparation>
</food>

<food>
   <name>lasagne</name>
   <preparation time="10" condition="noodles">Toaster</preparation>
</food>

 

Мне нужно определить, что атрибут «условие» может использоваться только при наличии атрибута «время». Таким образом, элемент, подобный следующему, должен быть недопустимым:

 <food>
   <name>toast</name>
   <preparation condition="noodles">Toaster</preparation>
</food>
 

Кроме того, атрибут «условие» должен иметь значение только из элемента «имя» или «устройство» (и я не знаю, решил ли я это, поскольку я не могу решить первое требование).

До сих пор я пытался определить оба требования с помощью assert . Но, к сожалению, он вообще не работает. Либо атрибут «условие» может быть использован в любое время и присвоено любое случайное значение, поэтому он игнорирует все ограничения. Или компилятор (я работаю с Oxygen XML-Editor) всегда выдает ошибку (оценка утверждения для элемента ‘food’ и типа схемы ‘#AnonType_foodmenues’ не удалась). Вот пример моего xsd-файла в том виде, в каком он есть, для дальнейшего анализа.

 XSD:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified" vc:minVersion="1.1"> 
    <xs:element name="menues">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="food" maxOccurs="unbounded" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="name">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:enumeration value="tea"/>
                                        <xs:enumeration value="sandwich"/>
                                        <xs:enumeration value="noodles"/>
                                        <xs:enumeration value="lasagne"/>
                                        <xs:enumeration value="pizza"/>
                                        <xs:enumeration value="juice"/>
                                        <xs:enumeration value="salat"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="preparation">
                                <xs:complexType>
                                    <xs:simpleContent>
                                        <xs:extension base="device">
                                            <xs:attribute name="time">
                                                <xs:simpleType>
                                                    <xs:restriction base="xs:integer"/>
                                                </xs:simpleType>
                                            </xs:attribute>
                                            <xs:attribute name="condition" type="xs:string"/>
                                        </xs:extension>
                                    </xs:simpleContent>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                        <xs:assert test="(preparation/@condition = (name, device)) or not (preparation/@condition)"/>
                        <xs:assert test="if (@condition) then (@time) else not (@condition)"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="device">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Ready to Go"/>
            <xs:enumeration value="Toaster"/>
            <xs:enumeration value="Cooking-Pot"/>
            <xs:enumeration value="Pan"/>
            <xs:enumeration value="Ofen"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>
 

Где я допустил ошибку?
Поскольку это не работает, я предполагаю, что мои утверждения неверны, но я не смог выяснить, были ли они пропущены или написаны неправильно. Как мне сделать так, чтобы атрибут «условие» можно было использовать только при наличии атрибута «время»?
Любая помощь приветствуется.

Ответ №1:

Я смог это понять: мне просто нужно было немного изменить утверждения. Первый должен был быть изменен <xs:assert test="(@time) or not (@condition)"/> на, чтобы разрешить использование атрибута «условие» только при наличии «времени». Второй я мог бы удалить, обобщив атрибут «name» на определение типа и переписав тип атрибутов «condition» в xs:union следующим образом:

 <xs:attribute name="condition">
   <xs:simpleType>
      <xs:union memberTypes="name device"/>
   </xs:simpleType>
</xs:attribute>