[XML-DEV Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Extensible schemas and xs:any


xsd xs any
Hi Murray,

Questions about XML Schema are best directed to xmlschema-dev@w....

> What I want is a main schema that has an element that is allowed to
> have a sequence of any child nodes. To do this I defined a global
> type that has an xs:any content model (is that the right way to say
> this?).

More or less -- more technically you have a global complex type whose
content type is element-only with a content model which is a sequence
that has a single particle whose term is a wildcard. But your
description is easier to read!

> The document element then has a child element of this type. (see
> Main.xsd below)
>
> Then I would like to have a 'sub' schema that xs:imports the main
> schema - and in this sub schema I over-ride the "Stuff" element from
> the main schema and specify that the Stuff element must have certain
> elements. (see Sub.xsd below)

There's a problem here in that you can't override things from one
schema to another unless you use xs:redefine, which means that both
schemas have to share the same namespace.

> Finally - if I construct an instance document that specifies the
> location of both schemas - and includes the Stuff element with child
> elements as declared in the Sub schema - I try to validate this
> hybrid document against both schemas. (see Stuff.xml below)

There's a problem here because in your instance document, the actual
Stuff element that you use is main:Stuff rather than sub:Stuff. In
fact you have to do it like because main:Things has to contain
main:Stuff (which is actually declared locally), but of course that
means that the content model of main:Stuff is main:StuffType rather
than sub:MyStuffType.

Basically, you're not going to achieve your goal in this way. I can
think of two other approaches that you might try, though:

First, you could create an "adapter schema", with the 'main' target
namespace, that imports your sub schema and redefines the
main:StuffType type so that it references the elements in your sub
schema. Your sub schema needs to declare the elements that you want to
use within main:Stuff at a global level, so that they can be referred
to from the adapter schema:

<xs:schema targetNamespace="http://redcone.gbst.com/Sub"
           xmlns:sub="http://redcone.gbst.com/Sub"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified" attributeFormDefault="qualified">

<xs:element name="MyStuffA" type="xs:string"/>
<xs:element name="MyStuffB" type="xs:string"/>

</xs:schema>

The adapter schema needs to import this schema and redefine the main
schema, as follows:

<xs:schema targetNamespace="http://redcone.gbst.com/Main"
           xmlns:main="http://redcone.gbst.com/Main"
           xmlns:sub="http://redcone.gbst.com/Sub"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified" attributeFormDefault="qualified">

<xs:import namespace="http://redcone.gbst.com/Sub"
           schemaLocation="Sub.xsd" />

<xs:redefine schemaLocation="Main.xsd">
  <xs:complexType name="StuffType">
    <xs:complexContent>
      <xs:restriction base="main:StuffType">
        <xs:sequence>
          <xs:element ref="sub:MyStuffA" />
          <xs:element ref="sub:MyStuffB" />
        </xs:sequence>
      </xs:restriction>
    </xs:complexContent>
  </xs:complexType>
</xs:redefine>

</xs:schema>

Then in your instance document, you should only refer to this schema.

The second approach is to use a substitution group. Since you want
sub:MyStuffA and sub:MyStuffB to appear in sequence, and only once,
you have to do this at the main:Stuff/sub:Stuff level. To use a
substitution group, declare main:Stuff at a global level within the
main schema:

<xs:schema targetNamespace="http://redcone.gbst.com/Main"
           xmlns:main="http://redcone.gbst.com/Main"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified" attributeFormDefault="qualified">

<xs:element name="Stuff" type="main:StuffType" />
           
<xs:complexType name="StuffType">
  <xs:sequence>
    <xs:any maxOccurs="unbounded"/>
  </xs:sequence>
</xs:complexType>
        
<xs:element name="Things">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Thing" type="xs:string"/>
      <xs:element ref="main:Stuff"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

</xs:schema>

Then in your Sub schema, declare sub:Stuff to be part of the
substitution group of main:Stuff, as follows:

<xs:schema targetNamespace="http://redcone.gbst.com/Sub"
           xmlns:main="http://redcone.gbst.com/Main"
           xmlns:sub="http://redcone.gbst.com/Sub"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified" attributeFormDefault="qualified">

<xs:import namespace="http://redcone.gbst.com/Main"
           schemaLocation="Main.xsd"/>

<xs:element name="Stuff" type="sub:MyStuffType"
            substitutionGroup="main:Stuff" />

<xs:complexType name="MyStuffType">
  <xs:complexContent>
    <xs:restriction base="main:StuffType">
      <xs:sequence>
        <xs:element name="MyStuffA" type="xs:string"/>
        <xs:element name="MyStuffB" type="xs:string"/>
      </xs:sequence>
    </xs:restriction >
  </xs:complexContent>
</xs:complexType>

</xs:schema>

Since sub:Stuff is part of the substitution group of main:Stuff, you
can replace main:Stuff with sub:Stuff wherever it appears within your
instance document. So your instance document should look like:

<main:Things xmlns:main="http://redcone.gbst.com/Main"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:sub="http://redcone.gbst.com/Sub"
             xsi:schemaLocation="http://redcone.gbst.com/Sub
                                 Sub.xsd">
  <main:Thing>String</main:Thing>
  <sub:Stuff>
    <sub:MyStuffA>blah</sub:MyStuffA>
    <sub:MyStuffB>blad</sub:MyStuffB>
  </sub:Stuff>
</main:Things>

Again, I'd only reference the one schema -- that for Sub.xsd -- though
it wouldn't do any harm if you referenced Main.xsd if you wanted to.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
 

Stylus Studio has published XML-DEV in RSS and ATOM formats, enabling users to easily subcribe to the list from their preferred news reader application.


Stylus Studio Sponsored Links are added links designed to provide related and additional information to the visitors of this website. they were not included by the author in the initial post. To view the content without the Sponsor Links please click here.

Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.