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 中一样:声明的元素类型必须可有效替换每个替换组头的类型。如果没有为元素指定类型,则默认为与第一个替换组头具有相同的类型。
抱歉问了这么长的问题。我会尽量让它变得尽可能简单。 我们正在研究模块化计算框架。框架从 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 中一样:声明的元素类型必须可有效替换每个替换组头的类型。如果没有为元素指定类型,则默认为与第一个替换组头具有相同的类型。