Re: [xsl] Schema Exploration...

Subject: Re: [xsl] Schema Exploration...
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Sat, 20 Apr 2002 10:58:29 +0100
Hi Mark,

> What I think I'd need to do is: Use your key stuff "key('elements',
> $node_name)" to select the nodes with the proper $node_name
>
> and
>
> then Select only the one for this node-set that is a descendant
> xs:element of the current xs:element node and does not have any
> ancestor xs:elements inbetween itself and the current "working
> node".

Hmm... yes, sorry -- I didn't remember your requirement to find only
xs:element elements within a certain other element. However, I assume
that you're using this to work out whether a particular element can
legally appear within another element? If so, you need to be aware
that other elements might be legal within a particular element but not
have a nested xs:element within that element's declaration because:

  - they're declared/referenced in a complex type referenced from this
    element
  - they're declared/referenced in a group referenced from this
    element's content model
  - they're declared/referenced in a complex type from which this
    complex type is derived by extension

and so on through multiple levels of redirection (groups referencing
groups, complex types in long derivation chains).

I think that in order to get information from a schema, the best thing
to do is to use a two step process where you first convert the schema
into a canonical representation of the XML Schema schema components
(something that represents its logical structure), and then search
within that structure for the information that you're after. This has
the advantage that you don't have to work around the multiple ways
that XML Schema has for representing everything.

(If you're more interested in the second step at the moment, then a
quick way to get a "canonical representation" is to lay down some
basic rules about the kinds of schemas you're going to assume your
XSLT stylesheet is dealing with, such as only having global complex
types derived from the ur-type and banning groups. But be prepared to
rework what you do when you move on to the "real thing".)

Having a canonical representation, in particular with groups and
derivations resolved (or ignored), it becomes easier to create the
key. You can create a key that combines the name that you're looking
for with the element (or complex type) in which it's contained. For
example if you're adopting a "Russian Doll" style, where all complex
types are anonymous and elements are all nested inside each other, you
can use the following:

<xsl:key name="elements-by-parent-element"
  match="xs:element//xs:element"
  use="concat(ancestor::xs:element[1]/@name, '//' (@name | @ref))" />

Each xs:element that occurs within another xs:element is indexed by a
combination of its closest ancestor xs:element's name and its own name
or ref attribute. For example, to find all the elements called 'foo'
nested inside elements called 'bar', you could use:

  key('elements-by-parent-element', 'bar//foo')

(The other thing that you'll have to tackle some point in the future
is namespace resolution of the 'ref' attributes.)
  
Cheers,

Jeni

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


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread