23

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?

poke
  • 369,085
  • 72
  • 557
  • 602

2 Answers2

37

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

Community
  • 1
  • 1
daveaglick
  • 3,600
  • 31
  • 45
  • Thank you, that looks quite good, I’ll try that. One question though, where does the `ea:` namespace prefix come from? Or is that the `name` the type definition gets in `A.xsd`? – poke Jun 20 '11 at 19:34
  • Just scroll way to right on the code window - it's referenced as the last attribute in the xs:schema element: `xmlns:ea="http://example.com/namespace/for/ElementA"`. You could give it whatever prefix you want, just as you can for the default target namespace (though everyone always chooses `xs` or `xsd` by convention). – daveaglick Jun 20 '11 at 19:51
  • Oh, didn’t bother to scroll that far and missed that, sorry xD Also thanks for your help, I’ll try this as soon as possible and post my results :) – poke Jun 20 '11 at 20:10
  • @somedave : I am also in a similar kind of situation. But my problem is that the elementB has no namespace declaration whereas only the elemenA has a namespace decalaration. So how should I include only that. Moreover there is no xsd for the element A. The only thing that has to be checked is that if the element A contains that namespace declaration. – Ashwin May 28 '12 at 04:20
  • If ElementA has a child element say Bazz, then validation library gives an error on that _"Element 'Bazz': This element is not expected"_. What could be the reason for that? – Jawaid Sep 10 '20 at 11:15
  • What should be the location of A.xsd? In my case B.xsd is trying to import A.xsd but it is not able to find the A.XSD.. – Sai Ram Reddy Oct 01 '20 at 05:18
0

You could use <xsd:import> tag to import a schema with another namespace.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Alexander Yezutov
  • 3,144
  • 2
  • 21
  • 23
  • 3
    Can you give me an example of how to use that with my example above? Your link does not really explain that.. – poke Jun 20 '11 at 16:16