redefine of redefine in series of schemas

I have a schema wich defines an element A in namespace "A-namespace".
I made it so that the A-element is extensible with child elements and 
attributes from another namespace, so that I can have e.g.


<?xml version="1.0" encoding="UTF-8"?>
<A xmlns="A-namespace" xmlns:b="B-namespace" b:B_Attribute="Hallo">
    <b:B/>
</A>

My schemas for the A-namespace are:

A.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="A-namespace" xmlns="A-namespace" 
xmlns:xs=http://www.w3.org/2001/XMLSchema
elementFormDefault="qualified" attributeFormDefault="unqualified">
    <!-- include base schema -->
    <xs:include schemaLocation="A-ns.xsd"/>
</xs:schema>

and A-ns.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
targetNamespace="A-namespace" xmlns="A-namespace" 
elementFormDefault="qualified" attributeFormDefault="unqualified">

<!-- attributes to A element -->
<xs:attributeGroup name="A_AttributeDefinition">
    <xs:attribute name="A_Attribute"/>
</xs:attributeGroup>

<!-- allow extension attributes to A element -->
<xs:attributeGroup name="A_AttributeExtension"></xs:attributeGroup>

<!-- allow extension child elements to A element -->
<xs:group name="A_ElementExtension"><xs:sequence/></xs:group>

<!-- A element complexType definition -->
<xs:complexType name="MycomplexTypeDefinition-A">
    <xs:sequence>
        <xs:group ref="A_ElementExtension" minOccurs="0" 
maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attributeGroup ref="A_AttributeDefinition"/>
    <xs:attributeGroup ref="A_AttributeExtension"/>
</xs:complexType>

<!-- A element definition -->
<xs:element name="A" type="MycomplexTypeDefinition-A"/>

</xs:schema>

For the B-namespace I have the following schemas:
- B.xsd is the main schema
- B-ns.xsd defines the elements of attributes of namespace "B-namespace"
- B-extensionToA.xsd defines how the elements/attributes from the 
B-namespace may be added to those of the A-namespace.

B.xsd:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema targetNamespace="A-namespace" xmlns="A-namespace" 
xmlns:xs=http://www.w3.org/2001/XMLSchema xmlns:b="B-namespace" 
elementFormDefault="qualified" attributeFormDefault="unqualified">

<xs:include schemaLocation="B-extensionToA.xsd"/>

</xs:schema>

B-ns.xsd:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema targetNamespace="B-namespace" 
xmlns="http://www.w3.org/2001/XMLSchema" 
xmlns:xs=http://www.w3.org/2001/XMLSchema xmlns:b="B-namespace" 
elementFormDefault="qualified" attributeFormDefault="unqualified">

<!-- define a B element that is extensible -->

<!-- attributes to B element - definition -->
<xs:attributeGroup name="B_AttributeDefinition">
    <xs:attribute name="B_Attribute"/> <!-- defines a simple attribute 
"B_Attribute" -->
</xs:attributeGroup>

<!-- allow extension attributes to B element -->
<xs:attributeGroup name="B_AttributeExtension"></xs:attributeGroup>
<!-- allow extension child elements to B element -->
<xs:group name="B_ElementExtension"><xs:sequence/></xs:group>

<!-- B element complexType definition -->
<xs:complexType name="MycomplexTypeDefinition-B">
    <xs:sequence>
    <xs:group ref="b:B_ElementExtension" minOccurs="0" 
maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attributeGroup ref="b:B_AttributeDefinition"/>
    <xs:attributeGroup ref="b:B_AttributeExtension"/>
</xs:complexType>

<!-- B element definition -->
<xs:element name="B" type="b:MycomplexTypeDefinition-B"/>
</xs:schema>

B_ExtensionToA.xsd:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema targetNamespace="A-namespace" xmlns="A-namespace" 
xmlns:b="B-namespace" xmlns:xs=http://www.w3.org/2001/XMLSchema 
elementFormDefault="qualified" attributeFormDefault="unqualified">

<!-- allow to use elements from the B-namespace in elements from the 
A-namespace -->
<xs:import namespace="B-namespace" schemaLocation="B-ns.xsd"/>

<!-- add extensions to A schema -->
<xs:redefine schemaLocation="A.xsd">

<!-- allow an attribute B_Attribute to the A element -->
<xs:attributeGroup name="A_AttributeExtension">
<xs:attributeGroup ref="A_AttributeExtension"/>
    <xs:attribute ref="b:B_Attribute"/>
</xs:attributeGroup>

<!-- allow B element to be a child element of A -->
<xs:group name="A_ElementExtension">
    <xs:sequence>
        <xs:group ref="A_ElementExtension"/>
        <xs:element ref="b:B" minOccurs="0"/>
    </xs:sequence>
</xs:group>
</xs:redefine>

</xs:schema>

This works great !

Now comes the difficult part:

I need to make the elements of as well the A-namespace as the B-namespace 
extensible so that I can add elements/attributes to A-elements and 
B-elements from a third namespace, the "C-namespace".

So I use the same mechanism in the B-namespace as I did for the A-namespace 
(see B-ns.xsd above).

So for the C-extension schema C-extensionToB.xsd I write:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs=http://www.w3.org/2001/XMLSchema 
targetNamespace="A-namespace"  xmlns="A-namespace" xmlns:b="B-namespace" 
xmlns:c="C-namespace">

<!-- import elements from C-namespace -->
<xs:import namespace="C-namespace" schemaLocation="C-ns.xsd"/>
<!--xs:import namespace="B-namespace" schemaLocation="B-ns.xsd"/-->


<xs:redefine schemaLocation="B-extensionToA.xsd">
    <!-- Add C element to A element -->
    <xs:group name="A_ElementExtension">
        <xs:sequence>
            <xs:group ref="A_ElementExtension"/>
            <xs:element ref="c:C"/>
        </xs:sequence>
    </xs:group>

    <!-- Add C element to B element --><!-- causes problems -->
    <xs:group name="B_ElementExtension">
        <xs:sequence>
            <xs:group ref="B_ElementExtension"/>
            <xs:element ref="c:C"/>
        </xs:sequence>
    </xs:group>
</xs:redefine>

</xs:schema>

With this I can add elements/attributes from the C-namespace to elements of 
the A-namespace, e.g.

<?xml version="1.0" encoding="UTF-8"?>
<A xmlns="A-namespace" xmlns:b="B-namespace" xmlns:c="C-namespace" 
b:B_Attribute="Hallo">
    <b:B/>
    <c:C/>
</A>

I can however NOT add elements from the C-namespace to those of the 
B-namespace.

For example, the following seems not to be possible - I get an error "cannot 
resolve the name 'B_ElementExtension_....." to a 'group' component

<?xml version="1.0" encoding="UTF-8"?>
<A xmlns="A-namespace" xmlns:b="B-namespace" xmlns:c="C-namespace" 
b:B_Attribute="Hallo">
    <b:B>
        <c:C/>
    </b:B>
    <c:C/>
</A>

It looks as using the "redefine" mechanism, it is only possible to add 
elements/attributes to elements of the namespace that is the 
"targetNamespace".

The problem seems to be in the snippet in the C_ExtensionToB.xsd:

<xs:group name="B_ElementExtension">
    <xs:sequence>
        <xs:group ref="B_ElementExtension"/>
        <xs:element ref="c:C"/>
    </xs:sequence>
</xs:group>

i.e. I am trying to add a C-element to an element in the B-namespace that is 
not the targetNamespace.

So my question: is there another way to make this possible ?

Of course I could make a single XSD (or a small set) to have all this, but 
there are some requirements from my employer:
- all the schemas for the A-namespace must reside in a single directory
- all the schemas for the B-namespace must reside in another single 
directory. This directory may not contain any copies of schemas from the 
A-directory

Until here, no problem. The next requirements is:
- all the schemas for the C-namespace must reside in a third directory. No 
copies of schemas from the A-directory nor from the B-directory may be 
present.
I.e. the C-schemas should use (unaltered) schemas from the A- and 
B-directory directly

The idea behind these requirements is that we have a fixed library of A- and 
B-Schemas, and that schema developers can define totally different schemas 
that have elements/attributes that extend as well the A- as B- elements.

The top element of all the instance documents will however ALWAYS be in the 
A-namespace.

Any proposals how this can be accomplished are very welcome.

Jozef

Jozef Aerts

XML4Pharma

Received on Friday, 26 September 2008 08:55:39 UTC