是否可以实例化双重扩展的complexType?

时间:2015-07-12 20:44:52

标签: xml inheritance xsd abstract extend

考虑以下情况:

我想在数据库中保存元素及其属性,这些元素从一个名为" PersistentElement"的常见但抽象的超类型扩展而来。现在,这些元素中的一些都具有特定属性,例如,它们都有一个名称,所有这些元素再次共享一个名为" NamedElement"的共同超单元,它同样是抽象的。这导致架构/ XSD看起来像这样:

<xs:element name="Database">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="elements" type="PersistentElement" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:complexType name="PersistentElement" abstract="true">
    <xs:attribute name="id" type="xs:ID"/>
</xs:complexType>

<xs:complexType name="NamedElement" abstract="true">
    <xs:complexContent>
        <xs:extension base="PersistentElement">
             <xs:attribute name="name" type="xs:string"/>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="ElementWithName">
    <xs:complexContent>
        <xs:extension base="NamedElement">
            <xs:element name="somethingElse" type="xs:string"/>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

现在我的问题: 这在XML中甚至可能吗?最明显的解决方法是将其中一个抽象元素作为xs:choice-type of element,但仅仅是出于好奇,而且因为我还在学习,我想知道是否可以使用双扩展抽象元素。我面临的问题是,我不能(或者更确切地说不知道如何)在相应的XML文件中实例化这样的元素。我想要的是:

<Database>
    <elements xsi:type="ElementWithName" id = "E1" name="testElement1" >
        <somethingElse>bla</somethingElse>
    </elements>
    <elements xsi:type="ElementWithName" id = "E2" name="testElement2" >
        <somethingElse>blub</somethingElse>
    </elements> 
</Database>

但是当我尝试验证时,这会给我一个错误,

Cvc-elt.4.2: Cannot Resolve 'ElementWithName' To A Type Definition For Element 'elements'.. Line '13', Column '66'.
Cvc-type.2: The Type Definition Cannot Be Abstract For Element Elements.. Line '13', Column '66'.
Cvc-complex-type.3.2.2: Attribute 'name' Is Not Allowed To Appear In Element 'elements'.. Line '13', Column '66'.
Cvc-complex-type.2.1: Element 'elements' Must Have No Character Or Element Information Item [children], Because The Type's Content Type Is Empty.. Line '16', Column '16'.

1 个答案:

答案 0 :(得分:0)

是的,您可以扩展已扩展的类型。

Xerces为您的XSD提供的错误消息是:

  

s4s-elt-invalid-content.1:&#39; ElementWithName&#39;的内容是   无效。元素&#39;元素&#39;无效,错位或发生   常。

xs:element/@name="somethingElse"中包裹xs:sequence可解决此错误。

以下是完整的,已更正的XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

  <xs:element name="Database">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="elements" type="PersistentElement" minOccurs="0"
                    maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="PersistentElement" abstract="true">
    <xs:attribute name="id" type="xs:ID"/>
  </xs:complexType>

  <xs:complexType name="NamedElement" abstract="true">
    <xs:complexContent>
      <xs:extension base="PersistentElement">
        <xs:attribute name="name" type="xs:string"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="ElementWithName">
    <xs:complexContent>
      <xs:extension base="NamedElement">
        <xs:sequence>
          <xs:element name="somethingElse" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>

以下是符合上述XSD的有效XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<Database xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="Database.xsd">
    <elements xsi:type="ElementWithName" id = "E1" name="testElement1" >
        <somethingElse>bla</somethingElse>
    </elements>
    <elements xsi:type="ElementWithName" id = "E2" name="testElement2" >
        <somethingElse>blub</somethingElse>
    </elements> 
</Database>