【问题标题】:How to define mutually exclusive attributes in XSD?如何在 XSD 中定义互斥属性?
【发布时间】:2016-02-18 07:48:27
【问题描述】:

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

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

如果它们共存于同一个元素上,那么验证就会失败?

【问题讨论】:

  • 你没有说&lt;tag name="default3"/&gt;是否应该是有效的(即当两个属性都不存在时)。
  • 是的,我想那是无效的,它需要其中之一
  • @ycomp 看我的回答。

标签: xml xsd xsd-validation


【解决方案1】:

根据https://www.w3.org/TR/xmlschema-1/#Selector 页面,我猜想用 xs:key 来处理属性之间的互斥量在其他解决方案中是行不通的。

它说,“在标记化时,总是返回最长的标记。”

【讨论】:

    【解决方案2】:

    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>
    

    【讨论】:

    • XSD 1.1 中的另一种方法是使用条件类型赋值:有一种类型允许 abc 但不允许 def,第二种类型允许 def 但不允许 abc,并使用 xs:alternative 在它们之间进行选择。
    【解决方案3】:

    使用 XSD 1.0,您可以使用xs:keyelement。

    <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 验证将失败。另一方面,&lt;xs: key&gt; 要求为元素定义一个键,因此必须存在两个属性之一。

    以下 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
    

    【讨论】:

    • 在 Visual Studio 2015 中,该错误可能具有误导性:The field 'def' is expecting at the most one value.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多