在XML Schema中定义必须实现的某些类型

时间:2014-12-16 14:41:47

标签: xml data-structures xsd

问题在于:有一个基础架构(game.xsd),它有一些" abstract"键入了类型。此模式必须单独有效。与此同时,我们需要有机会在另一个更具体的架构(customgame.xsd)中使用这个架构(game.xsd),其中所有架构都是#34; abstract"必须定义类型。

基本上,这个想法是强制模式的开发人员,他们使用初始模式(game.xsd),来定义某些类型。

xs的变种:redefine / xs:any已经被使用(不同命名空间的问题/定义过于宽松)

下面是两个模式的示例 - 初始" base" game.xsd 和"继承" customgame.xsd

<!-- Omitting definitions for GAME.XSD -->
<xs:schema>
  <xs:element name="BaseGameRule">
    <xs:complexType name="BaseGameRuleType"/>
  </xs:element>
</xs:schema>

<!-- Omitting definitions for CUSTOMGAME.XSD -->
<xs:schema>
  <!-- How to FORCE use to define BaseGameRuleType ? -->
  <xs:complexType name="BaseGameRuleType"/>
    <xs:sequence>
      <!-- Internal definitions -->
    </xs:sequence>
  </xs:complexType>
</xs:schema>

2 个答案:

答案 0 :(得分:1)

如果我说得对,那么你想要基础架构的应用程序配置文件。

首先是警告。

不要这样做。

这个想法可能很吸引人,但这不是开发人员友好的。我所熟知的是具有应用程序配置文件的GML示例。 GML架构是抽象的,当您想将其应用于地理对象(称为 features )时,您必须定义自己的应用程序配置文件架构。这就是强制开发人员实现某些类型所需的功能。

这导致巨大的开销。如果您需要某个用例,则必须执行应用程序配置文件架构。 XML Schema本身并不容易,GML模式非常复杂。模式也是一个规范级别,可以在编译时很好地处理,但在运行时不是那么容易。因此,您强制所有用例在编译时实现 - 或者在实现中非常复杂。

现在,如何解决它。您可以使用抽象元素和替换组来强制开发人员编写应用程序模式。

定义一些抽象基类型,比如AbstractGeometryType

定义该类型的抽象元素:

<element name="AbstractGeometry" type="gml:AbstractGeometryType" abstract="true" .../>

在复杂类型中使用此元素:

<complexType name="GeometryPropertyType">
    <sequence>
        <element ref="gml:AbstractGeometry"/>
    </sequence>
</complexType>

由于此元素是抽象的,因此它实际上不能出现在XML实例中。因此开发人员需要定义一些具体的元素,它将替换 abstract 元素。

要做到这一点,他们需要创建一个元素,该元素在抽象元素的替换组中具有从抽象基类型派生的类型。例如:

<element name="Point" type="gml:PointType" substitutionGroup="gml:AbstractGeometry"/>

现在Point可以替换AbstractGeometry中的GeometryPropertyType

您可以使用此trich并定义AbstractGameRule类型的AbstractGameRuleType元素。然后,开发人员需要创建CustomGameRuleType扩展AbstractGameRuleType和元素CustomGameRule,这将使用CustomGameRuleType并且可以使用替换组base:AbstractGameRule

但正如我所说,这是非常谨慎使用的。

答案 1 :(得分:0)

您可以在game.xsd中声明BaseGameRuleType是抽象的:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="BaseGameRuleType" abstract="true">
    <xs:sequence>
      <xs:element name="BaseElement1"/>
      <xs:element name="BaseElement2"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

然后用户可以在其customgame.xsd中扩展BaseGameRuleType

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="game.xsd"/>
  <xs:complexType name="GameRuleType">
    <xs:complexContent>
      <xs:extension base="BaseGameRuleType">
        <xs:sequence>
          <!-- Define additional elements here -->
          <xs:element name="CustomElement1"/>
          <xs:element name="CustomElement2"/>          
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:element name="BaseGameRule" type="GameRuleType"/>
</xs:schema>

这将允许以下XML有效:

<?xml version="1.0" encoding="UTF-8"?>
<BaseGameRule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:noNamespaceSchemaLocation="customgame.xsd">
  <BaseElement1/>
  <BaseElement2/>
  <CustomElement1/>
  <CustomElement2/>
</BaseGameRule>

如果您对可以和不能进入特定XSD的内容有广泛的要求,您可能需要考虑创建特定XSD的基于Schematron的验证器,因为这样可以更灵活地指定什么是什么,什么是什么不允许。