I have two XSDs that are definining different documents. Say A.xsd
defines an element ElementA
as the root, with some complex rules. Now B.xsd
defines an element ElementB
that is supposed to use ElementA
somewhere in between.
For example I want the XML file for ElementB
look like this:
<?xml version="1.0" encoding="utf-8"?>
<ElementB xmlns="http://example.com/namespace/for/ElementB">
<foo>Bla</foo>
<bar>Blub</bar>
<ElementA xmlns="http://example.com/namespace/for/ElementA">
<!-- ... -->
</ElementA>
</ElementB>
Then B.xsd
could look like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://example.com/namespace/for/ElementB" targetNamespace="http://example.com/namespace/for/ElementB" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="ElementB">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="xs:string" />
<xs:element name="bar" type="xs:string" />
<!-- And now I want to include ElementA somehow -->
<xs:element name="ElementA" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The thing is that I don‘t really want to clone the specification of ElementA
into B.xsd
, as there are also documents, that just have ElementA
as the root (i.e. ElementB
is some kind of container document).
So, how can I allow ElementA
within ElementB
while completely building on top of the already existent XSD?
There are actually two different ways to compose XML Schema documents: <xs:import>
and <xs:include>
. xs:include is intended to be used when the namespace of the containing document is the same as the one being referenced, so it's not quite what you're looking for. xs:import is better for your situation when you need to reference all (or a subset) of elements in the referenced schema and they're in a different target namespace. There's a question here on the differences: What's the difference between xsd:include and xsd:import?.
Anyway, back to this specific question. What you probably want is something like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
xmlns="http://example.com/namespace/for/ElementB"
targetNamespace="http://example.com/namespace/for/ElementB"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
xmlns:ea="http://example.com/namespace/for/ElementA">
<xs:import namespace="http://example.com/namespace/for/ElementA" schemaLocation="A.xsd" />
<xs:element name="ElementB">
<xs:complexType>
<xs:sequence>
<xs:element name="foo" type="xs:string" />
<xs:element name="bar" type="xs:string" />
<!-- This introduces a element named ElementA that uses the ComplexType ea:ElementA defined in A.xsd -->
<xs:element name="ElementA" type="ea:ElementA" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Though you'll need A.xsd to create a complex type for ElementA that you can use in B.xsd as shown.
This arcticle has some good information/examples and includes a discussion of some of the different composability strategies: http://www.xfront.com/ZeroOneOrManyNamespaces.html