2016-04-13 53 views
1

Böyle uzun bir soru için üzgünüz. Bunu olduğu kadar basit yapmaya çalışacağım. Modüler bir hesaplama çerçevesi üzerinde çalışıyoruz. Çerçeve, xml dosyasındaki yapılandırmayı okur ve xsd'ye karşı yapılandırmayı doğrulamak isteriz. Yeni modüller eklerken, xsd'nin bakım kolaylığı açısından olabildiğince basit olmasını istiyoruz.Xsd ve çoklu kalıtım

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

ve biz soyut çeşitli modül arayüzleri uygulanmasını ve modüller (örneğin ObjLoader: AbstractSource) uygulanmasını var: çerçevenin yapı (C#) şudur. xml yapısı aşağıdaki gibidir:

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

Şu ağır her yeni modül ile xsd değiştirmek için gerekliliğini önlemek için, aşağıdaki Test.xsd var:

<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> 

ve ortak 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> 
... 

Her bir modül (veya modüllerin grubu) kendi tanımıyla kendi xsd dosyası vardır ve bu dosya Test.xsd dahildir:

<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> 

Şimdiye kadar çok iyi ve her şey iyi çalışıyor. Modüller içeren her dll için xsd'yi sağlarız ve test.xsd'ye dahil ederiz. Ancak geliştirme sırasında, öncelikle bir tür olan ancak bir yan etki olarak başka bir işlem üretebilen modüller ortaya çıktı.

class GreatProcessingFilter : AbstractProcessor, 
           IFilter { ... } 

birden soyut unsurların bir ikamesi olabilecek bu tür unsurları idare edebilmek için elimizden xsd değiştirmek için bir yolu var mı: Bu bizim şu sınıf var gibi C# tarafında bir sorun değil mi? gibi bir şey:

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

cevap

0

XSD 1.1 substitutionGroup Özellikte birden QNames izin vermez. Bununla birlikte, çeşitli ikame grubu kafalarına tahsis edilen tiplerden dinamik olarak inşa edilen bir tipin verilmesi için çoklu ikame gruplarının bir üyesi olarak beyan edilen elemente neden olmaz. Bu yüzden muhtemelen aradığınız anlamda birden fazla kalıtım olarak nitelendirilmez. XML schemas with multiple inheritance ilgi alanını bulabilirsiniz.

[Ek, OP'nin yorumuna yanıt verme] XSD 1.1'de, üst düzey bir öğe birden fazla yer değiştirme grubuyla bildirilebilir; Daha sonra adlandırılmış öğelerin herhangi biri için (ikame grubu kafasındaki ilgili final özniteliği tarafından engellenmedikçe) yerine kullanılabilir. İkame grubu ilişkilerine ilişkin kısıtlamalar 1.0'da olduğu gibidir: beyan edilen elemanın türü, her bir ikame grubu kafasının tipi için geçerli olarak ikame edilebilir olmalıdır. Eleman için herhangi bir tip verilmediyse, varsayılan olarak ilk ikame grubu başkanı ile aynı tipte olacaktır.

+0

Cevabınız için teşekkür ederiz. Bana substitutionGroup'ta birden fazla QNames olasılığı hakkında daha fazla bilgi verir misiniz? – Petr

+0

Yanıt için eke bakınız. –

+0

Teşekkür ederim, ek olarak ... Muhtemelen başka bir yol bulmaya çalışacağım – Petr