在XML Schema中,为什么元素组标记甚至存在?

时间:2014-10-09 01:27:59

标签: xml xsd

根据我的理解,group用于创建以后可以引用的命名序列(选择,序列,全部)。

然而,当complexType可以用来完成同样的事情时,为什么这甚至是必要的呢?此外,它还要强大得多?这不是非干吗?更不用说group标记本质上既作为类型的定义,又同时可以是对该类型的引用,具体取决于您使用ref还是{{1} }属性。这不是非常令人困惑和不必要吗?或者我错过了一些重要的东西?

2 个答案:

答案 0 :(得分:2)

当您提出“为什么”问题时,有两种可能的方法可以回答:(a)委员会在指定此功能时的想法,以及(b)为什么我要使用此功能?即使你是委员会的成员,回答(a)也会非常困难;回答(b)通常更容易。有时答案是,不要试图使用这个功能:在XSD中肯定有一些东西,但命名的模型组不是其中之一。

本质上,它是一种重用和模块化机制。如果您有17个不同的元素,并且每个元素都允许以任何或多个元素Note,Author和/或DateCreated结束,那么将这三个元素放入一个组并引用该组会使您在添加第18个元素时更容易具有相同模式的元素,或者当您要添加DateModified作为附加选项时。另外一个模型组可以成为xs:deffines的目标 - 尽管如果可能的话我会避免使用重新定义。

根据是否存在@name或@ref属性,使用具有不同含义的一个元素名称(xs:group)的设计是您喜欢或不喜欢的。 (为什么他们把前门涂成红色?答案,他们喜欢这样。)XML没有严格的设计规则,不同的人会做出不同的设计选择,这并不是什么大不了的事。在设计XSD的具体语法时,有更糟糕的事情要抱怨。

答案 1 :(得分:1)

命名元素和属性组(xs:groupxs:attributeGroup)非常重要。

实际上,它们允许您定义一种代理复杂类型,但不受实际complexTypes的限制。

xs的限制:complexType

假设您像这样定义基本complexType:

<xs:complexType name="Base">
  (base element model)
</xs:complexType>

然后,您希望在XML架构中重用(base element model), 你只能通过派生出这样的其他complexType来做到这一点:

<xs:complexType name="Derived">
  <xs:complexContent>
    <xs:extension base="Base">
      (extension element model)
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

但是当扩展complexType时,新元素将作为序列添加到基本元素中。新的内容模型如下所示:

(base element model), (extension element model)

并且您不能有任何不同(例如,将扩展元素放在基本元素的前面)。这就是XSD中的类型扩展的工作方式!

在这里,我可以停下来说,所以设计了XSD语言。 但问题仍然存在。它为什么这么设计? 为什么在XSD中派生复杂类型不能更方便? 原因是这样的: 派生类型必须符合基本类型。 作为基础,你不能拥有任何东西的扩展!

假设您有一个知道如何处理A类型元素的软件。 该软件可能会假设实际上类型A可能会被扩展,但无论如何, 它必须能够在类型为A的元素中找到它所知道/期望的类型A ... 并且A类型固有的元素内容必须是第一个!

因此,使用complexType派生,您无法生成具有如下内容模型的Derived类型:

(extension element model), (base element model)

即将扩展元素放在基本元素的前面。

同样,你可能想知道为什么?也许,软件可以变得更复杂,甚至可以解决这个问题?

也许。但这将违背XSD语言中的一个基本原则:任何元素内容模型必须确定性。 这意味着对于任何元素序列,必须始终可以使用单一传递来识别特定内容模型(在XML模式中定义)。 如果软件只知道类型A,它必须首先以某种方式传递(extension element model)的元素,以便找到它知道如何处理的内容。当然,这不是确定性的!

xs:group如何保存当天

定义组时,它不应该像独立的complexType(能够分配给元素作为其类型)。 它只是一个可以在别处重复使用的内容模型。

您想将扩展元素放在基本元素的前面吗?没问题! 只需将Base定义为一个组:

<xs:group name="Base">
  (my base element model)
</xs:group>

然后,您可以像这样导出Derived complexType:

<xs:complexType name="Derived">
  <xs:sequence>
    (my extension element model)
    <xs:group ref="Base"/>
  </xs:sequence>
</xs:complexType>