RE: XPath's role (Was: Re: [xsl] Re: . in for)

Subject: RE: XPath's role (Was: Re: [xsl] Re: . in for)
From: "Michael Kay" <michael.h.kay@xxxxxxxxxxxx>
Date: Mon, 7 Jan 2002 14:37:03 -0000
> I agree that you need range variables to join two sequences in some
> cases, and that if you adhere to the principal that you should never
> have to drop into XSLT to combine two sequences to produce a third
> sequence then you need range variables.
>
> However, I am not yet convinced of that principal.
>
> First, I do not think that XPath needs to be able to do everything all
> by itself:
>
>   "XPath is designed to be embedded in a host language such as [XSLT
>    2.0] or [XQuery]."
>                                       (From Section 1 of XPath 2.0 WD)
>
> In my opinion, XPath should be kept simple - an expression language.
> It should be able to do the same kinds of things as you can do on the
> right side of a variable assignment in other programming languages,
> though oriented towards traversing a node tree in order to access
> information from XML.
>
Basically, there is no way in XSLT of constructing a sequence. The only
thing you can construct using XSLT instructions are trees. Given the
addition of sequences to the data model, we needed to provide some way of
constructing a sequence. Doing it in XPath, rather than by adding new XSLT
instructions, (a) gives us a greater level of commonality with XQuery, and
(b) gives better composability.

Using <xsl:for-each> at the XSLT level is no substitute for XPath
facilities. You can't use <xsl:for-each> to return those <employee>s whose
deparment is in a list of departments supplied as a parameter, because
<xsl:for-each> doesn't return anything, it constructs a tree, and the tree
can't contain original <employee> nodes, it can only contain copies. You can
use <xsl:for-each> to find *and process* those employees, if you want to do
both at the same time; but this lacks composability because you can't put
the list of selected employees into a variable and do other things with it,
such as selecting the top ten earners from among them, grouping them by
location, etc.

How else would you do:

<xsl:variable name="emps"
  select="//employee[some $d in $departments satisfies lower-case(./@dept) =
$d]"/>
<xsl:if test="count($emps) > 10">
  <xsl:for-each-group select="$emps" group-by="@location">
    ...
etc.

Mike Kay


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


Current Thread