如何在XSD中定义互斥属性?

时间:2015-11-17 03:10:54

标签: xml xsd xsd-validation

首先是代码片段......

<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不能作为同一元素的属性共存?

如果它们在同一个元素上共存,验证会失败吗?

3 个答案:

答案 0 :(得分:6)

XSD 1.0

可以使用xs:key使用聪明的技巧来完成。请参阅@Kachna's answer

请注意,如果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>

答案 1 :(得分:5)

使用 XSD 1.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

答案 2 :(得分:0)

根据https://www.w3.org/TR/xmlschema-1/#Selector页,我想在xs:key属性之间使用互斥锁不能在其他解决方案中使用。

它说:“进行令牌化时,总是返回最长的令牌。”