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

nik*_*kel 10 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> 
Run Code Online (Sandbox Code Playgroud)

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

跟进问题

那么这个限制功能有什么用呢?

有一种情况,我能想到; 当您必须在xml架构中验证包含受限类型的实例文档而不是基类型时.

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

此功能的任何其他用途?

C. *_*een 9

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

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

例如,让E成为

(a+, b+, c*){2}, (a+, b*, c+){3}
Run Code Online (Sandbox Code Playgroud)

让F成为

a{3,4}
Run Code Online (Sandbox Code Playgroud)

如果我们假设F中的所有内容都是对E中的某些内容的限制,并且E中的其他所有内容都应该保留,F是否意味着我们要将E限制为

(a{3,4}, b+, c*){2}, (a+, b*, c+)
Run Code Online (Sandbox Code Playgroud)

或者

(a+, b+, c*){2}, (a{3,4}, b*, c+)
Run Code Online (Sandbox Code Playgroud)

附录

@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>
Run Code Online (Sandbox Code Playgroud)

现在让我们假设我们希望类型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>
Run Code Online (Sandbox Code Playgroud)

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

后续问题

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

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

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