如何在XSD中参数化类型?

时间:2013-05-13 22:59:52

标签: xml xsd xml-namespaces

我有一个名为AdapterInputDataType的类型,它定义了某种输入数据的格式:

<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://companyname.org/AdapterInputDataTypeNS"
        xmlns:tns="http://companyname.org/AdapterInputDataTypeNS"
>

    <complexType name="AdapterInputDataType">
        <sequence>
            <element name="atomicElement" type="tns:AtomicElementType" minOccurs="0" maxOccurs="unbounded"/>
        </sequence>
    </complexType>

    <complexType name="AtomicElementType">
        <simpleContent>
            <extension base="tns:AtomicElementValueType">
                <attribute name="elementName" type="tns:AtomicElementNameType" use="required"/>
            </extension>
        </simpleContent>
    </complexType>

    <simpleType name="AtomicElementValueType">
        <union memberTypes="string long decimal dateTime boolean"/>
    </simpleType>

    <simpleType name="AtomicElementNameType">
        <restriction base="string">
            <enumeration value="foo"/>
            <enumeration value="bar"/>
            <enumeration value="baz"/>
        </restriction>
    </simpleType>

</schema>

AdapterInputDataType用于在多个名称空间内定义此类型的元素:

<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://companyname.org/adapter1"
        xmlns:tns="http://companyname.org/adapter1"
        xmlns:inptypns="http://companyname.org/AdapterInputDataTypeNS"
>

    <import namespace="http://companyname.org/AdapterInputDataTypeNS"/>

    <element name="adapterInputData" type="inptypns:AdapterInputDataType"/>

</schema>

<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://companyname.org/adapter2"
        xmlns:tns="http://companyname.org/adapter2"
        xmlns:inptypns="http://companyname.org/AdapterInputDataTypeNS"
>

    <import namespace="http://companyname.org/AdapterInputDataTypeNS"/>

    <element name="adapterInputData" type="inptypns:AdapterInputDataType"/>

</schema>

问题在于,对于每个名称空间,类型被导入到一组特定的允许值中,应该定义elementName属性。换句话说,在不同的命名空间中,AdapterInputDataType应该基于不同的AtomicElementNameType类型。

有没有办法在AdapterInputDataType定义中使用某种参数而不是AtomicElementNameType,并将不同的AtomicElementNameType类型放在不同的命名空间中作为此参数的值?

2 个答案:

答案 0 :(得分:2)

听起来像是替代团体的情况。

使用abstract =“true”将atomicAlement定义为全局元素声明,然后在各种特定于消息的模式文档中,您可以使用substitutionGroup =“tns:atomicElement”来定义具体元素,以使它们可以替代抽象元素。具体元素的类型必须与抽象元素的类型相同或派生;这通常通过给出抽象元素type =“xs:anyType”来实现。

答案 1 :(得分:0)

得到了一个解决方案(感谢Michael Kay关于替换组的提示)。

<schema xmlns="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://companyname.org/AdapterInputDataTypeNS"
                xmlns:tns="http://companyname.org/AdapterInputDataTypeNS"
>
        <import namespace="http://companyname.org/adapter1" schemaLocation="adapter1/ElementName.xsd"/>
        <import namespace="http://companyname.org/adapter2" schemaLocation="adapter2/ElementName.xsd"/>

        <element name="adapterInputData" type="tns:AdapterInputDataType" />

        <complexType name="AdapterInputDataType">
                <sequence>
                        <element name="atomicElement" type="tns:AtomicElementType" minOccurs="0" maxOccurs="unbounded"/>
                </sequence>
        </complexType>

        <complexType name="AtomicElementType">
                <sequence>
                        <element ref="tns:elementName" minOccurs="1" maxOccurs="1"/>
                        <element name="elementValue" type="tns:AtomicElementValueType" minOccurs="1" maxOccurs="1"/>
                </sequence>
        </complexType>

        <simpleType name="AtomicElementValueType">
                <union memberTypes="string long decimal dateTime boolean"/>
        </simpleType>

        <element name="elementName" type="string" abstract="true"/>

</schema>

<schema xmlns="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://companyname.org/adapter1"
                xmlns:tns="http://companyname.org/adapter1"
                xmlns:inptypns="http://companyname.org"
>

        <element name="elementName" type="tns:AtomicElementNameType" substitutionGroup="inptypns:elementName"/>

        <simpleType name="AtomicElementNameType">
                <restriction base="string">
                        <enumeration value="foo"/>
                        <enumeration value="bar"/>
                </restriction>
        </simpleType>

</schema>

<schema xmlns="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://companyname.org/adapter2"
                xmlns:tns="http://companyname.org/adapter2"
                xmlns:inptypns="http://companyname.org"
>

        <element name="elementName" type="tns:AtomicElementNameType" substitutionGroup="inptypns:elementName"/>

        <simpleType name="AtomicElementNameType">
                <restriction base="string">
                        <enumeration value="baz"/>
                </restriction>
        </simpleType>

</schema>

AtomicElementType在原帖中对其进行了一点修改。 elementName属性已替换为elementName子元素。原因是属性不能声明为抽象。 以下是针对此架构有效的数据示例:

<ans:adapterInputData xmlns:ans="http://companyname.org">
        <atomicElement>
                <ans1:elementName xmlns:ans1="http://companyname.org/adapter1">foo</ans1:elementName>
                <elementValue>hello</elementValue>
        </atomicElement>
        <atomicElement>
                <ans2:elementName xmlns:ans2="http://companyname.org/adapter2">baz</ans2:elementName>
                <elementValue>123</elementValue>
        </atomicElement>
</ans:adapterInputData>