在定义 XML 模式 (XSD) 时“选择”“组”元素是不是有效

Posted

技术标签:

【中文标题】在定义 XML 模式 (XSD) 时“选择”“组”元素是不是有效【英文标题】:Is it valid to have a 'choice' of 'group' elements when defining an XML Schema (XSD)在定义 XML 模式 (XSD) 时“选择”“组”元素是否有效 【发布时间】:2010-09-11 05:00:32 【问题描述】:

在定义 XML Schema (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) 不喜欢这样,但没有说明原因。它显示 行有错误,但没有说明错误是什么

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

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

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

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

架构组件约束:唯一 粒子属性

内容模型 必须形成使得在 ·验证·元素信息 项目序列,粒子组件 直接、间接或 ·隐含地·在其中 尝试·验证· 序列又可以是唯一的 未经审查就确定 该项目的内容或属性, 并且没有任何关于 在剩余的项目 顺序。

注意:此约束 为 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>

【讨论】:

【参考方案3】:

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

【讨论】:

以上是关于在定义 XML 模式 (XSD) 时“选择”“组”元素是不是有效的主要内容,如果未能解决你的问题,请参考以下文章

XSD.exe 和“循环组引用”

XSD:如何重新定义基本模式的标签

xsd 后缀文件用啥软件打开

使用Notepad ++ XML Tools创建XSD

针对多个模式定义验证 XML 文件

XML的验证模式DTD与XSD的区别