OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

 


 

   Re: [xml-dev] Extensible schemas and xs:any

[ Lists Home | Date Index | Thread Index ]

Hi Murray,

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

> 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/





 

News | XML in Industry | Calendar | XML Registry
Marketplace | Resources | MyXML.org | Sponsors | Privacy Statement

Copyright 2001 XML.org. This site is hosted by OASIS