0

我是 XML 模式的新手,我正在尝试弄清楚如何根据另一个值设置限制。

例如:

"State" = RI --> 有效值仅适用于该状态的 ABS "State" = 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>
4

1 回答 1

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 本身并没有指定表达测试的语言;很容易找到支持用 XPath 1.0 编写的断言或接受 XPath 2.0 的 Schematron 实现。

于 2013-03-09T23:47:57.307 回答