Hello,
I stumbled upon an XSD modelling problem, which is probably insolvable, but perhaps I overlook something and you might tell me.
The larger topic may be summarized "Modelling elements in foreign namespaces". Here, "foreign namespace" means a namespace different from the namespace of the root element. The root element namespace I call the local namespace. Accordingly, I speak of local and foreign XSD.
Now the *problem*: How to define multiple content models for an element name in a foreign namespace?
In other words: how to write the XSD so that <x:foo> elements (x denoting a foreign namespace) can have different content dependent on where it appears. In the following example, <x:foo> has different content dependent on if it's a child of <b> or <c>:
<a xmlns:x="http://example.com/x">
<b>
<y/>
<x:foo>
<x:ONE/>
<x:TWO/>
</x:foo>
</b>
<c>
<y/>
<x:foo>
<x:ONE/>
<x:TEN/>
</x:foo>
</c>
</a>
How to write XSD reflecting this?
In general, I see two approaches how to model elements in a foreign namespace:
(1) Element reference - e.g. <xs:element ref="x:foo"/>
(2) Imported type - e.g. <xs:element name="foo" type="x:footype"/>
Limitation of (1): the same reference QName means the same thing everywhere, so the document cannot contain <x:foo> elements with different content models, dependent on location.
Limitation of (2): as the type of a complex element describes its *children*, the namespace appears in the *children* of the element with the foreign type, not the element itself. So in the example, I would have to use a type from namespace x in order to describe <x:foo>'s parent - <b> and <c>. This is possible but twisted, as it is more natural to have the type definitions for <b> and <c> in the local XSD. Even worse, it gets really cumbersome when the element in the foreign namespace has siblings in the local namespace, as is the case in the example - note the <y> sibling of <x:foo>. So one has to make a wild construction - writing into the foreign XSD types describing local elements <b> and <c>, which will have to reference local element declarations or element types (example: reference <y>), in order to achieve the mixing of namespaces. Mental ping pong.
So would you agree that supporting variable content models for foreign element QNames is tricky and not straightforward at all - or do I overlook a simpler possibility?
Thank you for ideas or comments!
Hans-Jürgen
PS: Here come the XSDs which I wrote to model the document:
a.xsd:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:x="http://example.com/x" xmlns="http://example.com/a"
targetNamespace="http://example.com/a"
elementFormDefault="qualified">
<xs:import namespace="http://example.com/x" schemaLocation="x.xsd"/>
<xs:element name="a">
<xs:complexType>
<xs:sequence>
<xs:element name="b" type="x:bType"/>
<xs:element name="c" type="x:cType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="y" type="xs:string"/>
</xs:schema>
x.xsd:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:a="http://example.com/a" xmlns="http://example.com/x"
targetNamespace="http://example.com/x"
elementFormDefault="qualified">
<xs:import namespace="http://example.com/a" schemaLocation="a.xsd"/>
<xs:complexType name="bType">
<xs:sequence>
<xs:element ref="a:y"/>
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<xs:element name="ONE"/>
<xs:element name="TWO"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="cType">
<xs:sequence>
<xs:element ref="a:y"/>
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<xs:element name="ONE"/>
<xs:element name="TEN"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>