Xsd 和多重继承

Xsd and multiple inheritance

抱歉问了这么长的问题。我会尽量让它变得尽可能简单。 我们正在研究模块化计算框架。框架从 xml 文件中读取配置,我们想根据 xsd 验证配置。在添加新模块时,我们希望 xsd 在可维护性方面尽可能简单。 框架的结构如下(在c#中):

interface IModule { ... }
interface ISource : IModule { ... }
interface IFilter : IModule { ... }
interface IProcessor : IModule { ... }

我们有各种模块接口的抽象实现和模块的实现(例如 ObjLoader : AbstractSource)。 xml 的结构如下:

<Test>
    <Sources>
       <ObjLoader .../>
    </Sources>
    <Filters>
       ...
    </Filters>
    <Processors>
    ...
</Test>

目前,为了避免对每个新模块进行大量修改 xsd,我们有以下 test.xsd:

<xs:include schemaLocation="framework.xsd"/>
<xs:include ... modules /> 
<!-- adding includes for every module or group 
of modules is the only modification -->

<xs:element name="Test">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="this:Sources" 
                  minOccurs="1" 
                  maxOccurs="1"/>
      ...
    </xs:sequence>
  </xs:complexType>
</xs:element>

和常见的framework.xsd:

<xs:element name="Sources">
  <xs:complexType>
    <xs:choice maxOccurs="unbounded">
      <xs:element ref="this:AbstractSource"/>
    </xs:choice>
  </xs:complexType>
</xs:element>

<xs:element name="AbstractSource" 
            abstract="true"/>  

<xs:complexType name="ISource">
  <xs:complexContent>
    <xs:extension base="this:IModule">
      ...
    </xs:extension>
  </xs:complexContent>
</xs:complexType>
...

每个模块(或模块组)都有自己的 xsd 文件及其定义,该文件包含在 test.xsd:

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

<xs:element name="ObjLoader" 
    substitutionGroup="this:AbstractSource">
  <xs:complexType>
    <xs:complexContent>
      <xs:extension base="this:ISource">
        ...
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:element>

到目前为止一切顺利,一切正常。对于每个带有模块的 dll,我们提供相应的 xsd 并将其包含在 test.xsd 中。但是在开发过程中,出现了主要是某种类型但可以作为副作用产生另一种操作的模块。这在 c# 端不是问题,因为我们可以有以下 class:

class GreatProcessingFilter : AbstractProcessor, 
                              IFilter { ... }

有没有办法修改我们的 xsd 以能够处理可以替换多个抽象元素的元素?类似于:

<xs:element name="GreatProcessingFilter" 
            substitutionGroup="AbstractProcessor" 
            substitutionGroup="AbstractFilter"> ... 

XSD 1.1 允许 substitutionGroup 属性中有多个 QName。然而,它不会导致声明为多个替换组成员的元素被赋予一个类型,该类型是根据分配给各种替换组头的类型动态构造的。所以它可能不符合您正在寻找的意义上的多重继承。您可能会发现 XML schemas with multiple inheritance 感兴趣。

[补充,回应OP的评论]在XSD1.1中,一个顶层元素可以声明多个替换组;然后它可以替换任何指定的元素(除非被替换组头上的相关 final 属性阻止)。替换组从属关系的约束与 1.0 中一样:声明的元素类型必须可有效替换每个替换组头的类型。如果没有为元素指定类型,则默认为与第一个替换组头具有相同的类型。