- From: XML4Pharma <info@XML4Pharma.com>
- Date: Fri, 26 Sep 2008 10:03:53 +0200
- To: <xmlschema-dev@w3.org>
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