枚举限制基于另一个元素值

时间:2013-03-09 19:53:12

标签: xml xsd

我是XML架构的新手,我试图弄清楚如何根据其他值设置限制。

例如:

“州”= RI - >有效值仅适用于此状态的ABS “状态”= NC或CT有效值仅对于任一状态为Y

以下xml架构允许ABS和Y,无论状态如何:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

  <xs:element name="State"> 
    <xs:simpleType> 
      <xs:restriction base="xs:string"> 
        <xs:enumeration value="RI"/> 
        <xs:enumeration value="CT"/> 
        <xs:enumeration value="NC"/> 
      </xs:restriction> 
    </xs:simpleType> 
  </xs:element> 

  <xs:element name="PersonalInfo"> 
    <xs:complexType> 
      <xs:sequence> 
        <xs:element ref="State"/> 
        <xs:element ref="Car"/> 
      </xs:sequence> 
    </xs:complexType> 
  </xs:element> 

  <xs:element name="Manufacturer"> 
    <xs:simpleType> 
      <xs:restriction base="xs:string"> 
        <xs:enumeration value="MINI"/> 
      </xs:restriction> 
    </xs:simpleType> 
  </xs:element> 

  <xs:element name="Car"> 
    <xs:complexType> 
      <xs:sequence> 
        <xs:element ref="Manufacturer"/> 
        <xs:element ref="AntiLockBrakes"/> 
      </xs:sequence> 
    </xs:complexType> 
  </xs:element> 

  <xs:element name="AntiLockBrakes"> 
     <xs:simpleType> 
       <xs:restriction base="xs:string"> 
         <xs:enumeration value="ABS"/> 
         <xs:enumeration value="Y"/> 
       </xs:restriction> 
     </xs:simpleType> 
   </xs:element> 

 </xs:schema>

1 个答案:

答案 0 :(得分:3)

因为这类约束不是单独控制所涉及的单独元素的值,而是特定值的共同出现,所以它们通常被称为共现约束(或者更简洁 >共同约束)。

无上下文语法(以及基本上为XML文档编写无上下文语法的专用词汇表的模式语言 - 如DTD,Relax NG和XSD内容模型)在一般情况下不能很好地处理共同约束案例(虽然通常有特殊情况,但他们可以轻松处理)。

基于谓词的约束语言(如Schematron和XSD 1.1中的类似断言)通常能够方便地表达共同约束,因为它们是围绕谓词的思想构建的 - 事物是真实的,或者不成立,文档或元素或属性的 - 通常允许使用布尔运算符组合谓词。

因此,执行您描述的约束的最佳选择是使用Schematron或XSD 1.1中的断言。在XSD 1.1中(与Schematron不同),断言不允许在元素之外查看断言附加的类型,因此您需要将断言放在包含State和AntiLockBrakes元素的最小元素上;如果我正确地阅读架构,那将是PersonalInfo。 XSD 1.1模式可以使用断言来强制执行约束,方法是将PersonalInfo的声明更改为如下所示:

<xs:element name="PersonalInfo"> 
  <xs:complexType> 
    <xs:sequence> 
      <xs:element ref="State"/> 
      <xs:element ref="Car"/> 
    </xs:sequence> 
    <xs:assert test="
      (State = 'RI' and Car/AntiLockBrakes = 'Y')
      or 
      (State = ('NC', 'CT') and Car/AntiLockBrakes = 'ABS')
      "/>
  </xs:complexType> 
</xs:element>

xs:assert元素的'test'属性中的断言用XPath 2.0表示;正如您所料,有多种方式可以表达它。

Schematron的工作方式与此类似,但Schematron本身并未指定表达测试的语言;很容易找到Schematron实现,它们支持用XPath 1.0编写的断言,或者接受XPath 2.0。