如何从另一个xml架构扩展xml架构?

时间:2012-01-08 10:48:17

标签: xml xsd

我有一个类似于下面(resources.xml)的xml文档,带有相应的xml-schema(resources.xsd)。手动维护该xml文档(即添加/删除/编辑资源元素)。总共可能有500-1000个资源元素。每个资源可以是variantX或variantY(在“现实生活中”,还有一些变体)。

我想将xml文档拆分成几个xml文档。每个变体的一个xml文档(在本例中为X和Y),带有相应的新xml-schemas。每个变体的xml架构应该扩展原始架构,并且只为它的“variant”属性添加“硬编码”(固定?)值。

原因:避免在每个资源元素中重复“variant”属性。

这可能吗?每个变体的xml-schemas会是什么样的?在resources.xsd中需要做哪些更改?

欢迎任何其他建议:)

resources.xml中

    <?xml version="1.0" encoding="UTF-8"?>
    <resources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:noNamespaceSchemaLocation="resources.xsd">
        <resource name="res00" variant="X" >
            <property name="propA" value="..." />
            <property name="propB" value="..." />
        </resource>
        <resource name="res01" variant="X" >
            <property name="propA" value="..." />
            <property name="propB" value="..." />
        </resource>
        <resource name="res02" variant="Y" >
            <property name="propA" value="..." />
            <property name="propB" value="..." />
        </resource>
        <resource name="res03" variant="Y" >
            <property name="propA" value="..." />
            <property name="propB" value="..." />
        </resource>
    </resources>

resources.xsd

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:rb="http://example.org/resourcebase">

    <xs:complexType name="property">
        <xs:attribute name="name" type="xs:string" />
        <xs:attribute name="value" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="resource">
        <xs:sequence>
            <xs:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="variant" type="xs:string" use="required" />
    </xs:complexType>

    <xs:element name="resources">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="resource" type="resource" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

以下是我对此的看法。 variant = X的一个xml文档,引用到resourcesX.xsd。无需添加“variant”属性,因为它是由引用的resourcesX.xsd添加的。

resourcesX.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <resources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:noNamespaceSchemaLocation="resourceX.xsd">
        <resource name="res00" >
            <property name="propA" value="..." />
            <property name="propB" value="..." />
        </resource>
        <resource name="res01" >
            <property name="propA" value="..." />
            <property name="propB" value="..." />
        </resource>
    </resources>

variant = Y的另一个xml文档,引用到resourcesY.xsd。无需添加“variant”属性,因为它是由引用的resourcesY.xsd添加的。

resourcesY.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <resources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:noNamespaceSchemaLocation="resourceY.xsd">
        <resource name="res02" >
            <property name="propA" value="..." />
            <property name="propB" value="..." />
        </resource>
        <resource name="res03" >
            <property name="propA" value="..." />
            <property name="propB" value="..." />
        </resource>
    </resources>

resourceX.xsd和resourceY.xsd可以扩展resources.xsd吗?如果是这样,他们会是什么样子?需要在resources.xsd?

中进行任何更改

谢谢! /亚历

2 个答案:

答案 0 :(得分:1)

听起来你的目标是只在特定文件中拥有单个变体的资源,在这种情况下,而不是删除variant属性,将它移动到根{{1}是否有意义键入?这将允许文档结构保留有关正在表示哪个变体的信息,但也确保特定文件中的所有resources元素都与特定变体相关联。类似的东西:

resources.xsd

resource

和实例文档:

resourceX.xml

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:complexType name="property">
        <xs:attribute name="name" type="xs:string" />
        <xs:attribute name="value" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="resource">
        <xs:sequence>
            <xs:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required" />
    </xs:complexType>

    <xs:element name="resources">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="resource" type="resource" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
            <xs:attribute name="variant" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element>
</xs:schema>

答案 1 :(得分:1)

要将其拆分为多个模式文件,首先需要修改基础模式以仅包含将要共享的类型和元素,并且需要优化这些元素以允许扩展(或在派生模式中进行限制) )。在您的情况下,看起来property类型将被重用,resource类型将被限制,因此基本架构看起来像:

resources.xsd

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

    <xs:complexType name="property">
        <xs:attribute name="name" type="xs:string" />
        <xs:attribute name="value" type="xs:string" />
    </xs:complexType>

    <xs:complexType name="resource">
        <xs:sequence>
            <xs:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="variant" type="xs:string"/>
    </xs:complexType>

</xs:schema>

请注意,在资源中,variant属性不再是use="required",因为您的目标是不希望在实例文档中使用该属性。

对于架构的“X”变体,您需要包含resources.xsd架构,并且需要定义受限制的resourceX元素和包含resources元素。

resourceX.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:include schemaLocation="resources.xsd"/>

    <xs:complexType name="resourceX">
        <xs:complexContent>
            <xs:restriction base="resource">
                <xs:sequence>
                    <xs:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
                </xs:sequence>
                <xs:attribute name="name" type="xs:string" use="required" />
                <xs:attribute name="variant" type="xs:string" fixed="X"/>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="resources">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="resource" type="resourceX" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

xs:include语句将包含您之前定义的架构。新类型resourceX定义了对resource元素的限制,并将固定值Xvariant相关联。最后,resources元素被重新定义为resourceX类型的元素的集合,而不是resource

resourceY.xsd的定义方式与resourceX.xsd类似。