Re: Resolution of "ref" attribute in case of <override>

On 21 Oct 2009, at 15:22 , Kevin Braun wrote:

 > Here's an XSD 1.1 <override> question.

 > Suppose I have:

 > <schema ...  xmlns:qrs="uri:example.com">
 > <override ...>
 >   <complexType name="SomeType">
 >     <attributeGroup ref="qrs:abc"/>
 >   </complexType>
 > </override>
 > ...
 > </schema>

 > How will the prefix in the ref attribute in the attributeGroup
 > element be handled?

 > If D2' is the result of applying the xs:override transform, and D2'
 > contains an element information item that is identical to the one
 > for the <attributeGroup>, I expect it will have [in-scope
 > namespaces] based on what we see above; namely, the qrs prefix will
 > necessarily resolve to "uri:example.com".  Is that correct?

That's certainly the intent.  The namespace fixup rules of XSLT are
complicated enough that I don't want to say more about how it works
in detailuntil I have a chance to work the example through in more
detail.  But at a high level, the stylesheet knows the type of
attributeGroup/@ref, so it knows there are QNames around which may
depend on the current namespace bindings.  And when the node is
re-serialized in its new context, it should not have lost any
namespace bindings.  (The prefix may change, of course, but not the
expanded name denoted by qrs:abc.)

 > Also, a second question.  I don't speak XSLT, but the stylesheet
 > given for the transformation for xs:override includes a comment
 > that says :

 > <!--* change xs:override elements:  children which match
 >     * children of $overrideElement are replaced, others are
 >     * kept, and at the end all children of $overrideElement
 >     * not already inserted are added.
 >     *-->

 > The "at the end all children..." clause doesn't appear to be
 > consistent with the description that precedes the stylesheet.
 > Specifically, I don't see where a child of O1 that does not
 > correspond to a child of D2 would be put into D2'.  Perhaps I
 > misunderstand the comment, or perhaps it isn't consistent with the
 > XSLT that is there (again, I don't speak XSLT).  Is there an
 > inconsistency here?

The comment correctly describes the template which follows it, I
think.  And it also matches the behavior described in rule 4 of the
prose description.

The template applies to xs:override elements within D2, so we are
dealing with two override elements: O1, which is the override we are
trying to handle by performing the transformation, and E2 (the
override child of D2), which is in the process of being transformed
into a new override element O2, which will appear within D2'.

O2 contains (1) children corresponding to the children of E2.  If a
particular child of E2 matches some child of O1, then what O2
contains is the child of O1 (the child of E2 has been overridden by
the child of O1).  If a particular child of E2 matches no child of
O1, then O2 has that child unchanged.

O2 also contains (2) children corresponding to the children of O1.
If a child of O1 matches a child of E2, it's present in O2 as already
described above.  If a child of O1 matches no child of E2, it's
copied into O2 without change.

Example:

Schema document D1 overrides schema document D2, and its override
element contains declarations for elements A, B, and C.

   <schema xmlns="http://www.w3.org/2001/XMLSchema">
     <override id="d1o" schemaLocation="D2.xsd">
       <element name="A" type="anyURI"/>
       <element name="B" type="boolean"/>
       <element name="C" type="decimal"/>
     </override>
   </schema>

Schema document D2 overrides schema document D3, and the override
element contains declarations for elements C and D.

   <schema xmlns="http://www.w3.org/2001/XMLSchema">
     <override id="d2o" schemaLocation="D3.xsd">
       <element name="C" type="double"/>
       <element name="D" type="duration"/>
     </override>
   </schema>

Schema document D3 declares elements A, B, C, D, and E.

   <schema xmlns="http://www.w3.org/2001/XMLSchema">
     <element name="A" />
     <element name="B" />
     <element name="C" />
     <element name="D" />
     <element name="E" />
   </schema>

Observe first that the end result needs to have A, B, C, and D
declared as anyURI, boolean, decimal, and duration, respectively.

The first draft of override said, essentially, "That's too
complicated, it's not going to happen", and override only affected
elements declared in D2.  The result here would have been that of all
the overrides in D1, only the override of C would have had any
effect.  (At least, that's my recollection; I have not gone back to
review the details of the original proposal.)

The WG was troubled by the inconvenience this represented, and wanted
the overrides in D1 to affect not only declarations in D2 but
declarations in documents referenced by D2.  We spent some time
working out how to make this happen; the mechanism in the stylesheet
is the result.

The effect of the override of D2 in D1 is, according to the spec, the
same as an include of the transformed schema document D2', which
would look something like this:

   <schema xmlns="http://www.w3.org/2001/XMLSchema">
     <override id="d2o" schemaLocation="D3.xsd">
       <element name="C" type="decimal"/>
       <element name="D" type="duration"/>
       <element name="A" type="anyURI"/>
       <element name="B" type="boolean"/>
     </override>
   </schema>

Note that the overrides for A and B are included here, even though
they matched nothing in override d2o.  They are needed to ensure
that A and B are overridden WHEREVER they were declared.

The meaning of the override in D2' is, again, the same as the meaning
of an include on a transformed target D3', reading:

   <schema xmlns="http://www.w3.org/2001/XMLSchema">
     <element name="A" type="anyURI"/>
     <element name="B" type="boolean"/>
     <element name="C" type="decimal"/>
     <element name="D" type="duration"/>
     <element name="E" />
   </schema>

If we rewrite the overriding schema documents as well, to show the
change from override to include, we end up with an imaginare D1'
reading

   <schema xmlns="http://www.w3.org/2001/XMLSchema">
     <include id="d1o" schemaLocation="D2''.xsd"/>
   </schema>

And a D2'' reading

   <schema xmlns="http://www.w3.org/2001/XMLSchema">
     <include id="d2o" schemaLocation="D3'.xsd"/>
   </schema>

If the unmatched overrides of d1o had NOT been copied into the
modified version of d2o, then the final result would have had
a D3' of the form

   <schema xmlns="http://www.w3.org/2001/XMLSchema">
     <element name="A"/>
     <element name="B"/>
     <element name="C" type="decimal"/>
     <element name="D" type="duration"/>
     <element name="E" />
   </schema>

By copying even the unmatched children of O1 into O2, we ensure that
the declarations of O1 will override other declarations of the same
component name, no matter where those other declarations occur in the
target set of O1.  The transformation of include elements into
overide elements serves the same purpose.

I hope this helps.


-- 
****************************************************************
* C. M. Sperberg-McQueen, Black Mesa Technologies LLC
* http://www.blackmesatech.com
* http://cmsmcq.com/mib
* http://balisage.net
****************************************************************

Received on Thursday, 22 October 2009 00:12:20 UTC