by Eric van der Vlist is published by O'Reilly & Associates (ISBN: 0596004214)


Extensible and Open?

I wrote in the introduction to this chapter that the notions of "extensible" and "open" are largely independent. After all you have seen, you might even think that opening a schema can be an impediment to its extensibility. Let's say I have written an open model for the content of the book element that allows foreign nodes:

  <define name="book-content">
    <interleave>
      <attribute name="id"/>
      <attribute name="available"/>
      <element name="isbn">
        <ref name="isbn-content"/>
      </element>
      <element name="title">
        <ref name="title-content"/>
      </element>
      <zeroOrMore>
        <element name="author">
          <ref name="author-content"/>
        </element>
      </zeroOrMore>
      <zeroOrMore>
        <element name="character">
          <ref name="character-content"/>
        </element>
      </zeroOrMore>
      <ref name="foreign-nodes"/>
    </interleave>
  </define>

or:

 book-content =
    attribute id { text }
  & attribute available { text }
  & element isbn { isbn-content }
  & element title { title-content }
  & element author { author-content }*
  & element character { character-content }*
  & foreign-nodes

I have independently applied the tips for building an extensible schema (using interleave and containers) and also for defining an open schema (referencing a wildcard to allow foreign nodes). Unfortunately, if my schema is open, it's no longer very extensible.

Imagine that I want to add a couple of XLink attributes to define a link to a web page. I can't combine this new attribute with the existing schema using interleave. This new attribute would be considered a duplicate of the implicit definition of xlink:href already contained in the foreign-nodes wildcard.

The situation is similar for the addition of new elements. If I want to add an optional dc:copyright element, for instance, I can, but the constraint applied to this element will be in conflict with the lax definition of dc:copyright implicitly contained in the foreign-nodes wildcard. If the new constraint isn't met, RELAX NG will still find a match for a bogus dc:copyright element in the wildcard.

Does that mean that open schemas can't be extensible? Yes and no. While wildcards make open schemas less extensible, I can overcome that problem by extending schemas before opening them. To come back to the example, I'd better write a closed schema first (closed-schema.rng):

  <define name="book-content">
    <interleave>
      <attribute name="id"/>
      <attribute name="available"/>
      <element name="isbn">
        <ref name="isbn-content"/>
      </element>
      <element name="title">
        <ref name="title-content"/>
      </element>
      <zeroOrMore>
        <element name="author">
          <ref name="author-content"/>
        </element>
      </zeroOrMore>
      <zeroOrMore>
        <element name="character">
          <ref name="character-content"/>
        </element>
      </zeroOrMore>
    </interleave>
  </define>

or, in the compact syntax, closed-schema.rnc:

 book-content =
    attribute id { text }
  & attribute available { text }
  & element isbn { isbn-content }
  & element title { title-content }
  & element author { author-content }*
  & element character { character-content }*

I can then carefully keep this closed schema in a first document and extend it by inclusion and combination to become open:

  <include href="closed-schema.rng"/>
  <define name="book-content" combine="interleave">
    <ref name="foreign-nodes"/>
  </define>

or:

 include "closed-schema.rnc"
 book-content &= foreign-nodes

Applications would then use the open schema (the one produced by inclusion and combination) and derive the benefit as if the schema were natively open. The closed-schema would be available to extend the content model, redefine the foreign-node wildcard, and open the schema again in different ways.


This text is released under the Free Software Foundation GFDL.