XSD 1.1:属性与其他属性具有相同的值

问题描述

我应该使用 xsd 1.1 在 xml 中设计纸牌游戏。每张卡片都有一个元素“type”,它也定义了一种颜色以及一个元素“annotation”,它可以有几个属性,例如“function”和“until”(如示例中所示):

<card>
   <type color="black">One</type>
   <annotation function="drawcards">1</annotation>
</card> 

对于其中一些卡片,我应该将属性“直到”定义为一种条件,该条件应该被填满,并且只能具有与属性“颜色”或“功能”相同的值。前两个属性由枚举确定,并且只能具有某些值:

    <xs:simpleType name="color">
        <xs:restriction base="xs:string">
            <xs:enumeration value="black"/>
            <xs:enumeration value="red"/>
            <xs:enumeration value="blue"/>
            <xs:enumeration value="green"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="function">
        <xs:restriction base="xs:string">
            <xs:enumeration value="drawcards"/>
            <xs:enumeration value="cancel_turn"/>
            <xs:enumeration value="reverse"/>
            <xs:enumeration value="throwcards"/>
        </xs:restriction>
    </xs:simpleType>

如何在 xsd 文件中定义属性“直到”只能具有与“函数”或“颜色”中的值之一相似的值?我是否需要设置一个具有所有相同值的列表,还是有更短的方法

==编辑:==

根据要求,这里有一个完整的 XML 和 XSD,其中包含一个应该可以解决问题的断言。但是它不起作用 - 编译器总是抛出错误

XML:

<?xml version="1.0" encoding="UTF-8"?>
<cards xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xsi:noNamespaceSchemaLocation='TestAttribute.xsd'>
    
    <card>
        <type color="black">One</type>
        <annotation function="drawcards">1</annotation>
    </card> 
    
    <card>
        <type color="black">Two</type>
        <annotation function="throwcards">2</annotation>
    </card> 
    
    <card>
        <type color="black">Three</type>
        <annotation function="drawcards" until="black">1</annotation>
    </card> 
    
    <card>
        <type color="black">Five</type>
        <annotation function="reverse" until="red">1</annotation>
    </card> 
</cards>

XSD:

<?xml version="1.0" encoding="UTF-8"?>
<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="cards">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="card" maxOccurs="unbounded" minOccurs="0">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="type">
                            <xs:complexType>
                                <xs:simpleContent>
                                    <xs:extension base="xs:string">
                                        <xs:attribute name="color" use="required">
                                             <xs:simpleType>
                                                 <xs:restriction base="xs:string">
                                                     <xs:enumeration value="black"/>
                                                     <xs:enumeration value="red"/>
                                                     <xs:enumeration value="blue"/>
                                                     <xs:enumeration value="green"/>
                                                 </xs:restriction>
                                             </xs:simpleType>
                                         </xs:attribute>
                                    </xs:extension>                                                                      
                                </xs:simpleContent>
                            </xs:complexType>                            
                        </xs:element>
                        <xs:element name="annotation">
                            <xs:complexType>
                                <xs:simpleContent>
                                    <xs:extension base="xs:integer">
                                        <xs:attribute name="function" use="required">
                                            <xs:simpleType>
                                                <xs:restriction base="xs:string">
                                                    <xs:enumeration value="drawcards"/>
                                                    <xs:enumeration value="cancel_turn"/>
                                                    <xs:enumeration value="reverse"/>
                                                    <xs:enumeration value="throwcards"/>
                                                </xs:restriction>
                                            </xs:simpleType>
                                        </xs:attribute>
                                        <xs:attribute name="until"/>
                                        <xs:assert test="if (@until) then (@until = type/@color) or (@until = annotation/@function) else not (@until)"/>
                                    </xs:extension>
                                </xs:simpleContent>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>
</xs:schema>

解决方法

您使用断言,例如 <xs:assert test="@until = type/@color or @until = annotation/@function"/>

(但是,我不知道这是否正是您所描述的约束;使用诸如“某种条件”和“类似于的值”之类的词表明您的需求存在一定程度的模糊性。 .)

==稍后==

现在我们可以看到您的架构和实例文档:应该在 card 元素上定义断言(因为这是断言所需的所有数据“在范围内”的地方),然后它应该解决来自该上下文的相关数据:

<xs:assert test="annotation/@until = type/@color or annotation/@until = annotation/@function"/>

或者更简洁

<xs:assert test="annotation/@until = (type/@color,annotation/@function)"/>