[Bug 4767] New feature: xs:override

http://www.w3.org/Bugs/Public/show_bug.cgi?id=4767

           Summary: New feature: xs:override
           Product: XML Schema
           Version: 1.1 only
          Platform: PC
        OS/Version: Windows XP
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Structures: XSD Part 1
        AssignedTo: cmsmcq@w3.org
        ReportedBy: mike@saxonica.com
         QAContact: www-xml-schema-comments@w3.org


xs:override
========

Encouraged by a requirement from Eliot Kimber, and spurred on by Henry
Thompson, I offer the following proposal for a new feature in XML Schema 1.1

The requirement this addresses is one that xsl:redefine fails to meet - the
requirement to define a variant of a schema in which there is no constraint
that instances of the new schema should be valid instances of the old schema.
This requirement is common in customizing "industry-standard" schemas, in
defining successive versions of a schema, or in defining a family of messages
that include some components in common but differ in other significant details.
Examples of the variations that are possible include: changing an enumerated
code list by adding or removing values; making a required element optional;
adding a new element to the middle of a sequence; changing an attribute from
xs:double to xs:decimal, changing the "body" of an envelope structure to be a
specific required element. All of these changes can of course be achieved by
"copy and paste" modification, but this makes change management much more
difficult when the base schema changes.

The feature has strong similarities to XSLT's import feature, which allows
arbitrary redefinition of top-level templates, variables, functions, and other
declarations.

Proposed syntax
============

A new element xs:override is introduced, valid in the same places as
xs:redefine. Its content model is

<xs:override schemaLocation="uri">
  <xs:replace/>*
</xs:override>

The syntax of xs:replace is:

<xs:replace component="QName" ref="QName">
  ... content ...
</xs:replace>

where component is one of the top-level component names xs:element,
xs:attribute, xs:simpleType, xs:complexType, xs:group, xs:attributeGroup etc,
and the ref attribute refers to a named global component of that kind by its
expanded name. The content model for xs:replace is the same as the content
model of the relevant kind of component, for example if
component="xs:simpleType" then the content model is the same as that for
xs:simpleType, including all attributes other than the name attribute. This can
be defined in the S4S using conditional type assignment.

The semantics of xs:override are defined as follows. This specification is
written as a transformation to be applied to schema documents. It is done
strictly at the level of schema documents, and is applied before any
construction of schema components. The rules are as follows:

1. Let the transformed document set be the document retrieved using the URI
contained in the schemaLocation, together with all schema documents retrieved
by transitively following the URIs contained in xs:include, xs:import, and
xs:redefine elements in documents within the transformed document set.

2. Any xs:override element is a transformed document is processed by applying
this rule recursively. It is an error if there are cycles, that is, if this
process leads back to the original xs:override element.

3. Every document in the transformed document set is transformed using the XSLT
2.0 transformation below.

4. Every URI contained in an xs:include, xs:import, and xs:redefine element in
a transformed document is replaced by a sythetic URI that refers to the result
of transforming its original target.

5. The xs:override element is replaced by an xs:include element referring to
the result of transforming the document referenced in its schemaLocation
attribute.

5. The transformation that is applied is as follows, where $ov is the original
xs:override element and $schema is the xs:schema element of the document being
transformed. The transformation is assumed to apply to validated input
documents.

<xs:param name="ov" as="schema-element(xs:override)"/>
<xs:param name="schema" as="schema-element(xs:schema)"/>

<xsl:template match="schema-element(xs:schema)">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:copy-of select="xs:include | xs:import | xs:redefine"/>
    <xsl:apply-templates/>
  <xsl:copy>
</xsl:template>

<xsl:template match="xs:schema/*">
   <xsl:variable name="component" select="."/>
   <xsl:variable name="replacement"
select="$ov/xs:replace[@ref=f:componentName($component) and
@component=node-name($component)"/>
   <xsl:choose>
     <xsl:when test="$replacement">
       <xsl:copy>
         <xsl:attribute name="name" select="local-name()"/>
         <xsl:copy-of select="$replacement"/>
      </xsl:copy>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="."/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:function name="f:componentName" as="xs:QName">
  <xsl:param name="component" as="element()"/>
  <xsl:sequence select="QName($component/../@targetNamespace,
$component/@name)"/>
</xsl:function>

NOTES

A. No particular attempt has been made to handle the interaction between
replace and redefine elegantly; it is well-defined but may not meet user needs.

B. Components cannot be renamed by this mechanism. Components are referred to
by their "original" name, not by any name they might subsequently acquire as a
result of chameleon includes.

C. The effect of xs:override is confined to documents reachable via the given
URI.

Received on Tuesday, 26 June 2007 21:50:41 UTC