Redefine of redefine

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, without having to copy anything from the A-directory or B-directory (they aren't even allowed to do so).
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 09:00:42 UTC