Xml – How to extend an xml-schema from another xml-schema

xmlxsd

I have an xml document that looks something like below (resources.xml), with a corresponding xml-schema (resources.xsd). This xml document is manually maintained (i.e adding/removing/editing resource elements). In total there are maybe 500-1000 resource elements. Each resource can be of either variantX or variantY (in "real life", there are a few more variants).

I would like to split up the xml document into several xml documents. One xml document for each variant (X and Y in this case), with a corresponding new xml-schemas. The xml schemas for each variant, should extend the original schema and only add a "hardcoded" (fixed?) value for it's "variant" attribute.

Reason: To avoid repeating the "variant" attribute within each resource element.

Is this possible? What would the xml-schemas for each variant look like? What changes needs to be done in resources.xsd?

Any other suggestions are also welcomed 🙂

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>

Here's how I picture this. One xml document for variant=X, which referrers to resourcesX.xsd. No need to add the "variant" attribute, as it is added by the referred 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>

Another xml document for variant=Y, which referrers to resourcesY.xsd. No need to add the "variant" attribute, as it is added by the referred 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>

Can resourceX.xsd and resourceY.xsd extend the resources.xsd? If so, what would they look like? any changes needed to be made in resources.xsd?

Thanks!
/Alex

Best Answer

It sounds like your goal is to only have resources of a single variant in a particular file, in that case, instead of removing the variant attribute, would it make sense to move it to the root resources type? This would allow the document structure to retain the information about which variant is being represented, but also ensure that all of the resource elements in a particular file are associated with a particular variant. Something like:

resources.xsd

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

and instance document:

resourceX.xml

<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="resources.xsd"
        variant="X">
    <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>
Related Topic