XSD中如何定义互斥属性?
How to define mutually exclusive attributes in XSD?
###首先是代码片段...
<tag name="default" abc="10" def="20"> <!-- not valid, abc and def should be mutually exclusive -->
<tag name="default1" abc="10"> <!-- valid -->
<tag name="default2" def="20"> <!-- valid -->
###我想做什么...
我可以在我的 XSD
中添加什么,以便 @abc
和 @def
不能作为同一元素的属性共存?
因此,如果它们共存于同一元素上,验证将失败?
XSD 1.0
可以使用 xs:key
巧妙地完成。参见 。
请注意,如果某些解析器无法针对 xs:key
中的多个选定值失败,则它们可能会允许这两个属性。过去至少 one known case 发生过这种情况。
XSD 1.1
可以使用 xs:assert
:
<?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"
vc:minVersion="1.1">
<xs:element name="tag">
<xs:complexType>
<xs:sequence/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="abc" use="optional" type="xs:integer"/>
<xs:attribute name="def" use="optional" type="xs:integer"/>
<xs:assert test="(@abc and not(@def)) or (not(@abc) and @def)"/>
</xs:complexType>
</xs:element>
</xs:schema>
有了XSD1.0,就可以使用xs:key
元素了。
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="tag">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="abc" type="xs:integer"/>
<xs:attribute name="def" type="xs:integer"/>
</xs:complexType>
<xs:key name="attributeKey">
<xs:selector xpath="."/>
<xs:field xpath="@abc|@def"/>
</xs:key>
</xs:element>
编辑:
如果两个属性都存在(即使具有不同的值),这将创建两个键,因此 XML 验证将失败。另一方面,<xs: key>
要求为元素定义一个键,因此必须存在两个属性之一。
以下 XML 文档使用上面的 XSD 无效。 (我正在使用 oXygen 17.0):
<tag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="stack3.xsd" name="" abc="12" def="13"/>
错误:
cvc-identity-constraint.3: Field "./@abc|./@def" of identity constraint "attributeKey" matches more than one value within the scope of its selector; fields must match unique values
根据 https://www.w3.org/TR/xmlschema-1/#Selector 页面,我猜想在具有 xs:key 的属性之间使用互斥锁在其他解决方案中不起作用。
它说,“标记化时,总是返回可能的最长标记。”
###首先是代码片段...
<tag name="default" abc="10" def="20"> <!-- not valid, abc and def should be mutually exclusive -->
<tag name="default1" abc="10"> <!-- valid -->
<tag name="default2" def="20"> <!-- valid -->
###我想做什么...
我可以在我的 XSD
中添加什么,以便 @abc
和 @def
不能作为同一元素的属性共存?
因此,如果它们共存于同一元素上,验证将失败?
XSD 1.0
可以使用 xs:key
巧妙地完成。参见
请注意,如果某些解析器无法针对 xs:key
中的多个选定值失败,则它们可能会允许这两个属性。过去至少 one known case 发生过这种情况。
XSD 1.1
可以使用 xs:assert
:
<?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"
vc:minVersion="1.1">
<xs:element name="tag">
<xs:complexType>
<xs:sequence/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="abc" use="optional" type="xs:integer"/>
<xs:attribute name="def" use="optional" type="xs:integer"/>
<xs:assert test="(@abc and not(@def)) or (not(@abc) and @def)"/>
</xs:complexType>
</xs:element>
</xs:schema>
有了XSD1.0,就可以使用xs:key
元素了。
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="tag">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="abc" type="xs:integer"/>
<xs:attribute name="def" type="xs:integer"/>
</xs:complexType>
<xs:key name="attributeKey">
<xs:selector xpath="."/>
<xs:field xpath="@abc|@def"/>
</xs:key>
</xs:element>
编辑:
如果两个属性都存在(即使具有不同的值),这将创建两个键,因此 XML 验证将失败。另一方面,<xs: key>
要求为元素定义一个键,因此必须存在两个属性之一。
以下 XML 文档使用上面的 XSD 无效。 (我正在使用 oXygen 17.0):
<tag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="stack3.xsd" name="" abc="12" def="13"/>
错误:
cvc-identity-constraint.3: Field "./@abc|./@def" of identity constraint "attributeKey" matches more than one value within the scope of its selector; fields must match unique values
根据 https://www.w3.org/TR/xmlschema-1/#Selector 页面,我猜想在具有 xs:key 的属性之间使用互斥锁在其他解决方案中不起作用。
它说,“标记化时,总是返回可能的最长标记。”