具有多重继承的XML模式

时间:2009-07-29 08:24:39

标签: xml inheritance xsd

是否可以在XML模式中进行多重继承,如果是这样的话?

实施例

<xs:schema xmlns:xs="http://www.w3.org/2001/Schema" ....>

 <xs:complexType name="Account">
   <xs:sequence>
     <xs:element name="balance" type="xs:decimal"/>
     <xs:element name="accountNo" type="xs:string"/>
   </xs:sequence>
 </xs:complexType>

 <xs:complexType name="CreditCardAccount">
   <xs:complexContent>
    <xs:extension base="Account">
     <xs:sequence>
      <xs:element name="expiryDate" type="xs:date"/>
      <xs:element name="issuer" type="xs:string"/>
      <xs:element name="type" type="xs:string" use="required"/>
     </xs:sequence>
    </xs:extension>
   <xs:complexContent>
 </xs:complexType>

</xs:schema>

我的问题是; CreditCardAccount是否可以从多种类型继承而不仅仅是Account?

3 个答案:

答案 0 :(得分:23)

可以使用命名模型组和命名属性组来管理在某些方面类似于多重继承的东西;它是否像你想要的那样类似于多重继承只是你能说出来的东西。

假设您有复杂类型Account(如上所示)和Customer,并且您希望从每个类型继承复杂类型的CreditCardAccount。正如其他人指出的那样,您不能在复杂类型定义中指定两种基本类型。但您可以将Account和Customer类型的内容模型打包到命名的模型组中,并从类型定义中引用相应的命名组。

<xs:group name="Account">
  <xs:sequence>
    <xs:element name="balance" type="xs:decimal"/>
    <xs:element name="accountNo" type="xs:string"/>
  </xs:sequence>
</xs:group>

<xs:group name="Customer">
  <xs:sequence>
    <xs:element name="custid" type="xs:int"/>
    <xs:element name="street" type="xs:string"/>
    <xs:element name="city" type="xs:string"/>
    <xs:element name="phone" type="xs:string"/>
  </xs:sequence>
</xs:group>

<xs:complexType name="Account">
  <xs:sequence>
    <xs:group ref="Account"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="Customer">
  <xs:sequence>
    <xs:group ref="Customer"/>
  </xs:sequence>
</xs:complexType>

然后您可以参考CreditCardAccount的两个命名组:

<xs:complexType name="CreditCardAccount">
  <xs:sequence>
    <xs:group ref="Account"/>
    <xs:group ref="Customer"/>
    <xs:element name="expiryDate" type="xs:date"/>
    <xs:element name="issuer" type="xs:string"/>
    <xs:element name="type" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

在这种情况下,XSD验证者不会将客户,帐户和CreditCardAccount类型视为相关,这可能会也可能不会。

当然,更简单的方法是使用元素作为信息包,并定义元素Account,Customer和CreditCardAccount,CreditCardAccount包含( surprise )Account元素和Customer元素。

答案 1 :(得分:13)

不,这是不可能的。 XML Schema 1.0 Spec定义了only one extension element

答案 2 :(得分:1)

另一种策略是使用链式扩展。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://mycompany.com/contacts"
           xmlns="http://mycompany.com/contacts"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:complexType name="HaveIdentifier">
        <xs:sequence>
            <xs:element name="UUID" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="HasAssociations">
        <xs:complexContent>
            <xs:extension base="HaveIdentifier">
                <xs:sequence>
                    <xs:element name="Associations" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="Address">
        <xs:complexContent>
            <xs:extension base="HaveIdentifier">
                <xs:sequence>
                    <xs:element name="Street" type="xs:string" minOccurs="0" maxOccurs="1"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="Contact">
        <xs:complexContent>
            <xs:extension base="HasAssociations">
                <xs:sequence>
                    <xs:element name="Name" type="xs:string" minOccurs="0" maxOccurs="1"/>
                    <xs:element name="Addresses" type="Address" minOccurs="0" maxOccurs="unbounded"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
</xs:schema>

但请注意,您将无法使用“HasAssociations”但不具有“HaveIdentifier”的复杂类型