部分模式包含在多个子模式中

时间:2013-06-17 21:07:23

标签: include xsd reusability

我的目标是创建一个模块化XML模式,在一个文件中有一些共享类型可用于所有子模式文件。解决这个问题的最佳方法是什么?

示例:

假设我想构建一个描述有关汽车和自行车的XML文档的XML架构。然后,我为XML创建了一个模式,我将其分为4个文件:vehicles.xsdcars.xsdbikes.xsdtypes.xsdvehicles.xsd包括cars.xsdbikes.xsd,它们都包含types.xsd。我在使用命令

尝试这个例子时注意到了
xmllint --schema vehicles.xsd vehicles.xml

它验证正常,即使我期望由于types.xsd的双重包含而导致出现冲突(这导致了complexType vehicleType的2个定义)。从<include>cars.xsd 中移除bikes.xsd标记也可以正常验证。有人可以向我解释这里发生了什么吗?

XML和XSD:

vehicles.xml:

<vehicles xmlns="http://example.com/vehicles">
  <cars>
    <car make="Porsche" model="911" />
    <car make="Porsche" model="911" />
  </cars>
  <bikes>
    <bike make="Harley-Davidson" model="WL" />
    <bike make="Yamaha" model="XS650" />
  </bikes>
</vehicles>

vehicles.xsd:

<xs:schema
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:vh="http://example.com/vehicles"
  targetNamespace="http://example.com/vehicles"
  elementFormDefault="qualified">

  <xs:include schemaLocation="cars.xsd" />
  <xs:include schemaLocation="bikes.xsd" />

  <xs:element name="vehicles">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="vh:cars" />
        <xs:element ref="vh:bikes" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

cars.xsd:

<xs:schema
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:vh="http://example.com/vehicles"
  targetNamespace="http://example.com/vehicles"
  elementFormDefault="qualified">

  <xs:include schemaLocation="types.xsd" />

  <xs:element name="cars">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="car" type="vh:vehicleType"
          minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

bikes.xsd:

<xs:schema
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:vh="http://example.com/vehicles"
  targetNamespace="http://example.com/vehicles"
  elementFormDefault="qualified">

  <xs:include schemaLocation="types.xsd" />

  <xs:element name="bikes">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="bike" type="vh:vehicleType"
          minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

types.xsd

<xs:schema
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://example.com/vehicles">

  <xs:complexType name="vehicleType">
    <xs:attribute name="make" type="xs:string" />
    <xs:attribute name="model" type="xs:string" />
  </xs:complexType>
</xs:schema>

2 个答案:

答案 0 :(得分:2)

大多数XSD处理器在被要求包含类似types.xsd的架构文档时,会注意到它们已经包含它,并且它们避免第二次包含它; XSD规范明确鼓励这一点。这就是为什么你没有收到关于双重包含的错误消息,以及为什么单个包含对合并的情况工作正常。

但是,一般情况下,如果通过从单个顶级驱动程序文件中完成所有内容来简化操作,那么XSD处理器之间的互操作性会略微提高一些。如果您使用了这个习惯用法,那么您将删除所有架构文档中的xs:include元素,并创建一个或多个新的驱动程序文档,其中只包含包含内容(如果您只需要一个架构,则为一个;如果您需要不同,则为多个驱动程序文档)具有不同元素集的模式)。

类似的注意事项适用于在xs:import元素上使用schemaLocation属性。使用这个习语有助于避免情况(特别是涉及重新定义和参考周期的情况),这些情况会产生与不同处理器截然不同的结果。

答案 1 :(得分:0)

从XML模式的W3C规范中,我相信它的目的是能够拥有模块化模式,并且可以在需要时将它们包含在内。 xml处理器的预处理器应首先解析所有包含和&#34; import&#34;

我确实有一个广泛的架构,它被分解成小块模块。这适用于许多xlm处理器和xml编辑器。