#xml #xsd #annotations #attributes #assert
Вопрос:
Я работаю над карточной игрой, которая должна отображать несколько состояний и изменять их в зависимости от условий. Чтобы понять это, у меня есть элемент <properties>
, который дается каждой карточке в качестве обязательного элемента. Каждое свойство может иметь ряд атрибутов, как показано в этом примере для xsd:
<xs:element name="properties" maxOccurs="1">
<xs:complexType>
<xs:attribute name="type" type="MyAttributeType"/>
<xs:attribute name="color" type="color"/>
<xs:attribute name="number" type="xs:integer"/>
</xs:complexType>
</xs:element>
Они properties
не только отображают свойства каждой карты, но и задают свойства всего игрового поля.
Теперь у меня есть задача сделать так, чтобы карта могла изменять эти свойства игрового поля в зависимости от своих собственных свойств. Для этого я должен реализовать тип connected_condition
, который запускается только при выполнении определенного условия. Например:
<connected_condition><properties color='red'/><properties color='green'/></connected_condition/>
Это условие, например, должно изменить цвет игрового поля на зеленый вместо красного, когда отображается карта со свойством «красный».
Однако — поскольку мы здесь имеем дело с атрибутами, connected_condition
подобное может быть допустимым, но нарушит задачу, которую я должен выполнить:
<connected_condition><properties color='red' type='heart'/><properties color='green'/></connected_condition/>
Общее количество максимум двух атрибутов должно быть допустимым в контексте connected_condition
, независимо от того, есть ли один или два элемента properties
внутри. Но также одно и то же свойство должно быть в состоянии измениться (например, красный на зеленый), и я не нашел способа использовать 2 раза один и тот же атрибут в одном элементе свойств в a connected_condition
. Чтобы решить эту проблему, я ищу способ ограничить общее количество атрибутов, которые могут использоваться в контексте элемента connected_condition
. Предпочтительно шляпа утверждения говорит что-то вроде: «подсчитайте все атрибуты из всех дочерних элементов в connected_condition и будьте ложны, если их больше 2».
Также это должно происходить без ограничения количества атрибутов, используемых в одном элементе properties
, который присваивается каждой карте. В лучшем случае это приведет к такой карте, как эта:
XSD:
<xs:element name="card">
<xs:complexType>
<xs:sequence>
<xs:element name='name' type='xs:string'/>
<xs:element name="properties" type='properties'/> <!--should have all 3 of its attributes-->
<xs:element name='connected_condition' minOccurs='0' maxOccurs='1'>
<xs:complexType>
<xs:sequence>
<xs:element name="properties" type='properties' maxOccurs='2'/> <!--attributes limited to 2-->
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name='properties'>
<xs:restriction base="xs:string">
<xs:attribute name="type" type="MyAttributeType"/>
<xs:attribute name="color" type="color"/>
<xs:attribute name="number" type="xs:integer"/>
</xs:restriction>
</xs:simpleType>
XML:
<card>
<name>Card 1</name>
<properties type='heart' color='red' number='7'/>
<connected_condition><properties color='red'/><properties color='green'/></connected_condition>
<text>Here goes the text</text>
</card>
Есть ли способ ограничить общее количество атрибутов, когда их элемент используется в качестве дочернего элемента с помощью утверждения?
Ответ №1:
Я не уверен, не лучше ли ограничить тип, но утверждение в форме
<xs:element name="card">
<xs:complexType>
<xs:sequence>
<xs:element name='name' type='xs:string'/>
<xs:element name="properties" type='properties'/> <!--should have all 3 of its attributes-->
<xs:element name='connected_condition' minOccurs='0' maxOccurs='1'>
<xs:complexType>
<xs:sequence>
<xs:element name="properties" type='properties' maxOccurs='2'/> <!--attributes limited to 2-->
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:assert test="every $prop in connected_condition/properties satisfies count($prop/@*) le 2"/>
</xs:complexType>
</xs:element>
это может выражать ваше ограничение на количество атрибутов каждого properties
элемента внутри connected_condition
.
Ваш комментарий наводит на мысль, что вы скорее хотите <xs:assert test="count(connected_condition//@*) le 2"/>
.
Комментарии:
1. К сожалению, я не могу подтвердить. Кажется, это ничего не меняет. При применении его к коду и последующем добавлении более 1 атрибута на свойство он остается действительным.
2. @DanielJanz, ваше описание было неясным, например, в образце указано «атрибуты ограничены 2», а опубликованный таким образом код
count($prop/@*) le 2
допускает до двух атрибутов (le 2
«меньше или равно 2»). Измените номер на1
, если это то, что вы хотели. Я даже не уверен, хотите ли вы проверить каждыйproperties
элемент или все из них, опубликованный код предполагает, что вы хотите проверить количество атрибутов каждогоproperties
дочернего элементаconnected_connection
элемента.3. Ах нет, извините за неудобства. Речь идет о количестве всех атрибутов, суммированных по всему
properties
элементу внутриconnected_condition
. Поэтому независимо от того, есть ли только одинproperties
элемент или два, общее количество атрибутов, используемых внутриconnected_condition
, не должно превышать двух.4. Больше никаких идей о том, как справиться с этой задачей? Я все еще в растерянности.
5. Не помогает ли редактирование с
<xs:assert test="count(connected_condition//@*) le 2"/>
помощью?