XSD 1.1:限制元素的整体属性数量

问题描述

我正在开发一种纸牌游戏,该游戏应该显示多种状态并根据条件进行更改。为了实现这一点,我有一个元素 <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 的上下文中,最多两个属性的总数应该是有效的。但同样的属性也应该能够改变(例如红色到绿色),我没有找到一种方法可以在 connected_condition 中的一个属性元素中使用 2 次相同的属性。为了解决这个问题,我正在寻找一种方法来限制可以在元素 connected_condition 的上下文中使用的属性总数。最好断言帽子这样说:“计算 connected_condition 内所有子元素的所有属性,如果超过 2,则为 false”。 此外,这不应限制在赋予每张卡片本身的单个元素 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>

当使用断言将元素用作子元素时,有没有办法限制属性的总数?

解决方法

我不确定限制类型不是更好,而是以

形式的断言
   <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"/>