复杂类型的XML模式限制:完全重新定义?

时间:2013-02-10 12:06:25

标签: xml xsd

在XML Schema中向complexTypes添加限制时,是否有必要重写complexType定义中使用的所有元素?如果是这样,为什么不能只重用现有的元素定义并覆盖新的受限制的元素?

例如,在下面;当我只想限制字段国家时,我是否应该重新编写所有3个字段?

<xs:complexType name="customer">
  <xs:sequence>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
    <xs:element name="country" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="Norwegian_customer">
  <xs:complexContent>
    <xs:restriction base="customer">
      <xs:sequence>
        <xs:element name="firstname" type="xs:string"/>
        <xs:element name="lastname" type="xs:string"/>
        <xs:element name="country" type="xs:string" fixed="Norway"/>
      </xs:sequence>
    </xs:restriction>
  </xs:complexContent>
</xs:complexType> 

所以,从下面的答案可以清楚地看出为什么我们必须重写整个类型。

跟进问题

那么这个限制功能的用途是什么?

我能想到的一种情况;当你必须在xml架构中验证包含受限类型的实例文档来代替基类型时。

说,如果“B”是基本类型并且其限制为“B *”。在Schema Document期望类型为“B”的元素的位置包含“B *”的任何实例文档都可以工作。我们不必为每个受限类型编写单独的规则。(属性“xsi:type”in实例文档将使用正确的类型对其进行验证。)对吗?

此功能的其他任何用途?

1 个答案:

答案 0 :(得分:9)

您的第一个问题是“在XML Schema中向complexTypes添加限制时,是否有必要重写complexType定义中使用的所有元素?”不,只有您想要成为限制类型定义的一部分。但是,是的,所有应该成为限制的一部分。限制中的内容模型必须独立作为该类型的内容模型的完整定义。 (另一方面,它不必指定所有属性;除非另有说明,否则它们将继承而不进行更改。)

你的第二个问题是“为什么它不能只重用现有的元素定义并覆盖新的受限制的元素?”这是一个合理的问题。答案有点棘手:考虑两个任意内容模型E和F.现在,我们想要将F解释为E的限制,它只提到我们想要改变的E中的元素和模型组,并且省略了对元素的任何提及我们想要的模型组。在一般情况下,这是一个可溶性问题吗?是否保证有独特的解决方案?你可能会觉得两种情况下的答案都是肯定的,但对于当时的XSD设计人员来说这似乎并不明显,而且今天对我来说似乎并不明显。

例如,让E为

(a+, b+, c*){2}, (a+, b*, c+){3}

让F为

a{3,4}

如果我们假设F中的所有内容都是E中某些内容的限制而E中的其他内容都应该单独存在,那么F是否意味着我们要将E限制为

(a{3,4}, b+, c*){2}, (a+, b*, c+)

(a+, b+, c*){2}, (a{3,4}, b*, c+)

附录

@nikel要求提供XSD示例。上面的例子已经是一个XSD示例了,所以我想是“XSD语法中的一个例子”。我认为该提议应该是以下语法应该有效。首先我们有基本类型,E:

<xs:complexType name="E">
  <xs:sequence>
    <xs:sequence minOccurs="2" maxOccurs="2">
      <xs:element ref="a" maxOccurs="unbounded"/>
      <xs:element ref="b" maxOccurs="unbounded"/>
      <xs:element ref="c" minOccurs="0" 
                          maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:sequence minOccurs="3" maxOccurs="3">
      <xs:element ref="a" maxOccurs="unbounded"/>
      <xs:element ref="b" minOccurs="0" 
                          maxOccurs="unbounded"/>
      <xs:element ref="c" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:sequence>
</xs:complexType>

现在让我们假设我们希望类型F能够在不指定完整内容模型的情况下限制E.所以我们写了

<xs:complexType name="F">
  <xs:complexContent>
    <xs:restriction base="tns:E">
      <xs:sequence>
        <xs:element ref="a" minOccurs="3" maxOccurs="4"/>          
      </xs:sequence>        
    </xs:restriction>
  </xs:complexContent>
</xs:complexType>

F的有效内容模型应该在这里?

后续问题

你问,基本上,“在这种情况下,限制的用途是什么?”

合理的问题。你建议的答案是好的。更一般地说,有时我们发现知道类型B *的每个实例都是B类实例是有用的; XSD中的限制派生旨在保证不变量。有时,定义具有两个或更多具体限制的抽象类型似乎是有帮助的;这有助于确保抽象基类型的各种具体实现彼此很好地相关,即使没有任何其他是任何其他的子集或超集。

可能存在(没有:大量的)通过限制的推导可以在XSD中更清晰,更简单,更方便的方式;不必重复整个内容模型就是其中之一。但是,对于XSD中的所有内容来说都是如此。唯一真正的优点是很多人似乎都想使用它来支持它。