Извините за такой длинный вопрос. Я постараюсь сделать это так просто, как только получится. Мы работаем над модульной вычислительной структурой. Структура читает конфигурацию из xml-файла, и мы хотели бы проверить конфигурацию на xsd. Добавляя новые модули, мы хотели бы, чтобы xsd был как можно более простым в смысле ремонтопригодности. Структура рамок является следующее (в C#):Xsd и множественное наследование
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 GreatProcessingFilter : AbstractProcessor,
IFilter { ... }
Есть ли способ, чтобы изменить наш XSD, чтобы иметь возможность обрабатывать такие элементы, которые могут быть подменой нескольких абстрактных элементов? Что-то вроде:
<xs:element name="GreatProcessingFilter"
substitutionGroup="AbstractProcessor"
substitutionGroup="AbstractFilter"> ...
Благодарим вас за ответ. Не могли бы вы рассказать мне больше о возможности множественных QNames в substitutionGroup? – Petr
См. Дополнение к ответам. –
Спасибо, за добавление ... Я, вероятно, попытаюсь найти другой способ – Petr