9

定义 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"> 行有错误,但没有说明错误是什么

4

3 回答 3

9

我不是 XML 专家,尽管我经常使用它。这不是我通常会做这种结构的方式。我更喜欢单独的复杂类型,而不是选择两组(请参阅此答案的最后)。

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

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

Schema 组件约束:唯一的粒子属性

必须形成一个内容模型,使得在元素信息项序列的“验证”期间,可以唯一地确定其中直接、间接或“隐含”包含的粒子组件,用来依次验证序列中的每个项目没有检查该项目的内容或属性,也没有关于序列其余部分的项目的任何信息。

注意:此约束为 XML Schema 重构了 [XML 1.0(第二版)] 和 SGML 的等效约束。鉴于元素替换组和通配符的存在,此约束的简明表达是困难的,请参阅对唯一粒子属性约束(非规范)(§H)的进一步讨论。

例如,下面的两个组在同一个选择中是非法的,因为它们的每个第一个元素都是“名称”,这意味着您无法识别您正在查看的组。但是,如果 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>
于 2008-09-19T13:24:21.287 回答
2

是的。这是因为 ReservationGroup 和 CancellationGroup 都有相同的第一个元素 - 一个“reservation-type”元素,在 ReservationGroup 中分别具有固定值“Reservation”和 CancellationGroup 中的“Cancellation”。

于 2008-09-19T14:07:33.943 回答
1

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

于 2008-09-19T12:24:18.043 回答