定义XML模式(XSD)时具有"选择""组"元素是否有效?

时间:2020-03-06 14:25:40  来源:igfitidea点击:

定义XML模式(XSD)时具有"选择"或者"组"元素是否有效

即以下有效

<xs:complexType name="HeaderType">
  <xs:sequence>
    <xs:element name="reservation-number" type="ReservationNumberType" minOccurs="1" maxOccurs="1" nillable="false" />
    <xs:choice minOccurs="1" maxOccurs="1">
      <xs:group ref="ReservationGroup" />
      <xs:group ref="CancellationGroup"/>
    </xs:choice>
  </xs:sequence>
</xs:complexType>

XML消息可以表示例如新的保留或者现有保留的取消。

如果消息是用于保留的,则它必须包括ReservationGroup组中定义的所有元素。

如果是取消,则它必须包括CancellationGroup组中定义的所有元素。

由于某种原因,我的XML编辑器(Eclipse)不喜欢这种方式,但是没有说明原因。它显示在<xs:complexType name =" HeaderType">行上有错误,但没有说明错误是什么

解决方案

这是否有效取决于组的内容:如果它们是"序列"或者"选择"模型组,则完全合法; "所有"模型组的问题更大,在这种情况下通常是不允许的。

我不是XML专家,尽管我经常使用它。这不是我通常采用这种结构的方式。我宁愿使用单独的复杂类型,也不愿选择两组(请参阅本答案的最后)。

我怀疑问题在于ReservationGroup和CancellationGroup以相同的元素开头,在这种情况下,我们将违反Schema Component Constraint:Unique Particle Attribution(如下)。

http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/#cos-nonambig

Schema Component Constraint: Unique
  Particle Attribution 
  
  A content model
  must be formed such that during
  ·validation· of an element information
  item sequence, the particle component
  contained directly, indirectly or
  ·implicitly· therein with which to
  attempt to ·validate· each item in the
  sequence in turn can be uniquely
  determined without examining the
  content or attributes of that item,
  and without any information about the
  items in the remainder of the
  sequence.
  
  Note: This constraint
  reconstructs for XML Schema the
  equivalent constraints of [XML 1.0
  (Second Edition)] and SGML. Given the
  presence of element substitution
  groups and wildcards, the concise
  expression of this constraint is
  difficult, see Analysis of the Unique
  Particle Attribution Constraint
  (non-normative) (§H) for further
  discussion.

例如,以下两个组在同一选择中都是非法的,因为它们的第一个元素都是"名称",这意味着我们无法识别正在查看的组。但是,ReservationGroup的第一个元素与Cancellation组不同
(可能是resDate和cancDate),那么那是有效的。

编辑:我从来没有遇到过这种问题,我认为它令人着迷的是,组的定义完全合法,但是如果将它们放在一起进行选择,那么由于每个组的定义,该选择将变得非法。 。

无法形成合法选择的组

<xs:group name="ReservationGroup">
    <xs:sequence>
        <xs:element name="date"/>
        <xs:element name="name"/>
        <xs:element name="address"/>
    </xs:sequence>
</xs:group>

<xs:group name="CancellationGroup">
    <xs:sequence>
        <xs:element name="date"/>
        <xs:element name="name"/>
        <xs:element name="address"/>
    </xs:sequence>
</xs:group>

可以构成合法选择的组

<xs:group name="ReservationGroup">
    <xs:sequence>
        <xs:element name="resDate"/>
        <xs:element name="name"/>
        <xs:element name="address"/>
    </xs:sequence>
</xs:group>

<xs:group name="CancellationGroup">
    <xs:sequence>
        <xs:element name="cancDate"/>
        <xs:element name="name"/>
        <xs:element name="address"/>
    </xs:sequence>
</xs:group>

正如我上面提到的,我会用复杂的类型来做这种事情。是的,它增加了另一个元素,但它似乎是显而易见的方式,我喜欢显而易见性。

<xs:complexType name="HeaderType">
  <xs:sequence>
    <xs:element name="reservation-number" type="ReservationNumberType" minOccurs="1" maxOccurs="1" nillable="false" />
    <xs:choice minOccurs="1" maxOccurs="1">
      <xs:element name="reservation" type="ReservationType" />
      <xs:element name="cancellation" type="CancellationType" />
    </xs:choice>
  </xs:sequence>
</xs:complexType>

是的。这是因为ReservationGroup和CancellationGroup具有相同的第一个元素,即" reservation-type"元素,其ReservationGroup中的固定值分别为" Reservation",而Cancellationgroup中的固定值分别为" Cancellation"。