Re: Defining common wrapper elements across schemas

Hi Justin,

> A substitutionGroup in the Content schema won't work because none of
> the substituted elements (e.g. my:Stuff, other:Vocabularies) share a
> common base type.

At the very least, they could all share the base type xs:anyType,
which is the very top of the type hierarchy. I think that an approach
using an abstract element with the type xs:anyType would work quite
well here, if you didn't care about being able to constrain the actual
content model of the <c:Content> element for a particular combination
of content schemas.

> Is there another, simpler way to allow wrapper elements around
> elements from schemas that aren't known at design-time? (Does this
> question make any sense?).

If you don't want to use substitution groups, you could take an
"adapter schema" approach. In this approach, validation is carried out
using at least three schemas:

  - the wrapper schema (targetNamespace = c)
  - content schemas (targetNamespace = anything)
  - an adapter schema (targetNamespace = c)

The wrapper schema declares the <c:Content> element with an
empty type, in the wrapper namespace:

<xs:element name="Content" type="c:ContentType"/>
<xs:complexType name="ContentType" />

The content schemas declare their elements, in whatever namespaces.

The adapter schema is in the wrapper namespace. It imports the content
schemas that you want to allow for the particular document, and
*redefines* the c:ContentType type from the wrapper schema in order to
specify the actual content model of the <c:Content> element. Something
like:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:c="wrapper"
           targetNamespace="wrapper">

<xs:import namespace="meta" href="meta.xsd" />
<xs:import namespace="my" href="my.xsd" />
<xs:import namespace="other" href="other.xsd" />

<xs:redefine href="wrapper.xsd">

  <xs:complexType name="ContentType">
    <xs:extension base="c:ContentType">
      <xs:sequence>
        <xs:element ref="meta:Metadata" />
        <xs:choice>
          <xs:element ref="my:Stuff" />
          <xs:element ref="other:Vocabularies" />
        </xs:choice>
      </xs:sequence>
    </xs:extension>
  </xs:complexType>

</xs:redefine>

</xs:schema>

The wrapper schema itself stays the same, but you can use different
adapter schemas to restrict the actual content of the <c:Content>
element.


An alternative, again if you didn't care about the actual content
model of <c:Content>, would be to simply define the c:ContentType type
such that it can contain any global element in any namespace:

<xs:complexType name="ContentType">
  <xs:sequence maxOccurs="unbounded">
    <xs:any namespace="##other" processContents="strict" />
  </xs:sequence>
</xs:complexType>

The elements that were actually allowed within the <c:Content> element
would then depend on what other schemas were used when validating a
document.

Cheers,

Jeni

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

Received on Thursday, 20 November 2003 04:54:22 UTC