XSD 1.1:仅当存在另一个不需要的属性时才使用属性
XSD 1.1: Use of attribute only when another not required attribute is present
我应该为一个简单的小型餐厅模拟器写一个 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>
此外,属性“condition”应该只能有来自元素“name”或“device”的值(我不知道,如果我解决了那个,因为我无法解决第一个需求).
到目前为止,我尝试用断言来定义这两个需求。但遗憾的是它根本不起作用。任何时候都可以使用属性“条件”并赋予任何随机值,因此它会忽略所有限制。或者编译器(我正在使用 Oxygen XML-Editor)总是抛出错误(元素 'food' ond 模式类型 '#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>
我哪里弄错了?
由于这不起作用,我假设我的断言是错误的,但我无法弄清楚它们是放错了地方还是写错了。如何使属性“条件”只能在属性“时间”存在时使用?
非常感谢任何帮助。
我弄明白了:
我只需要稍微改变断言。第一个要更改为 <xs:assert test="(@time) or not (@condition)"/>
以便仅允许在存在“时间”时使用属性“条件”。第二个我可以删除,方法是将属性“名称”概括为类型定义并重写 xs:union 中的“条件”属性类型,如下所示:
<xs:attribute name="condition">
<xs:simpleType>
<xs:union memberTypes="name device"/>
</xs:simpleType>
</xs:attribute>
我应该为一个简单的小型餐厅模拟器写一个 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>
此外,属性“condition”应该只能有来自元素“name”或“device”的值(我不知道,如果我解决了那个,因为我无法解决第一个需求).
到目前为止,我尝试用断言来定义这两个需求。但遗憾的是它根本不起作用。任何时候都可以使用属性“条件”并赋予任何随机值,因此它会忽略所有限制。或者编译器(我正在使用 Oxygen XML-Editor)总是抛出错误(元素 'food' ond 模式类型 '#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>
我哪里弄错了? 由于这不起作用,我假设我的断言是错误的,但我无法弄清楚它们是放错了地方还是写错了。如何使属性“条件”只能在属性“时间”存在时使用? 非常感谢任何帮助。
我弄明白了:
我只需要稍微改变断言。第一个要更改为 <xs:assert test="(@time) or not (@condition)"/>
以便仅允许在存在“时间”时使用属性“条件”。第二个我可以删除,方法是将属性“名称”概括为类型定义并重写 xs:union 中的“条件”属性类型,如下所示:
<xs:attribute name="condition">
<xs:simpleType>
<xs:union memberTypes="name device"/>
</xs:simpleType>
</xs:attribute>