Re: key and document()

James Clark <jjc@jclark.com> writes:

> Right.  The description of the key() function says:
> 
> "...it returns a node-set
> containing the nodes ***in the same document as the context node*** that
> have a value for the named key equal to this string"

Aargh!  Either I missed this or I simply overlooked its implications.
It would certainly be helpful to make it a little bit more explicit in
the draft.  Especially, an example using document() would bring the
point home very clearly.

> Unfortunately, that's not allowed by the syntax.  You have do do
> something like:
> 
>   <xsl:for-each select="document('db.xml')">
>      <xsl:apply-templates select="key($name,$value)"/>
>   </xsl:for-each>

Oops, you're right!  Oh, this is terrible.  Unless I am mistaken, it
means there is no way to express selection of keys, from another
document, using an expression.

What is missing is a way to establish a context node for the purpose
of evaluating a function call.  The only way permitted by the syntax
is to pass this context node as an additional argument to the
function.  But key() did not anticipate the need for such a
`contextual' argument.

Suppose I want to bind a variable to the node set corresponding to
key($name,$value) in document('db.xml'). (1) There is no way to
achieve this for a top level variable. (2) Using your technique, the
variable can only be defined for the scope of the for-each.

> > Does it not follow from this that I can never have a key that contains
> > nodes from multiple documents?
> > 
> > If a multi-document spanning key is desired, then it must be simulated
> > by means of union expressions (thus forcing database merging to be
> > expressed at each point of use rather than at the point of
> > `definition').
> 
> Right.  In this respect, key() is just like id().

Actually, the idea of using union expressions suffers from the same
shortcoming as described above since only expressions occurring in the
scope of the `trick' for-each can manage it.

My proposal of the day (:-) is to allow a 3rd optional argument to
key() to permit specification of a context node (or node set of
context nodes).  Thus key($name,$key,E) would mean the union of
evaluating key($name,$key) for each node in the node set denoted by
expression E.  Naturally, if E is omitted, it would default to
"current()".

Thus, hopefully, I could write:

<variable name="db.1" select="document('db1.xml')"/>
...
<variable name="db.n" select="document('dbn.xml')"/>
...
<variable name="foo" select="key($name,$value,$db.1|...|$db.n)"/>

It's still not very nice to have to specify the union at the point of
use, instead of being able to define globally an aggregated collection
of keys spanning multiple documents, but at least it would be a great
improvement over not being able to express such an idiom at all.

Cheers,

-- 
Dr. Denys Duchier			Denys.Duchier@ps.uni-sb.de
Forschungsbereich Programmiersysteme	(Programming Systems Lab)
Universitaet des Saarlandes, Geb. 45	http://www.ps.uni-sb.de/~duchier
Postfach 15 11 50			Phone: +49 681 302 5618
66041 Saarbruecken, Germany		Fax:   +49 681 302 5615

Received on Tuesday, 24 August 1999 08:21:32 UTC