This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: XPath's role (Was: Re: Re: . in for)
- From: Jeni Tennison <jeni at jenitennison dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Mon, 7 Jan 2002 16:25:05 +0000
- Subject: Re: XPath's role (Was: Re: [xsl] Re: . in for)
- Organization: Jeni Tennison Consulting Ltd
- References: <000d01c19790$44a01070$465169d5@pcukmka>
- Reply-to: xsl-list at lists dot mulberrytech dot com
Hi Mike,
> 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.
I disagree with the statement that there is no way of constructing a
sequence in XSLT, assuming that you were talking about XSLT 2.0 plus
XPath 1.0. XSLT 2.0 gives us xsl:function, and xsl:function enables us
to construct sequences because it allows us to return things other
than trees.
Writing your own (often recursive) functions with xsl:function is
undoubtedly too complicated for basic sequence generation, which is
why I suggested a simple mapping operator.
The other thing that I think makes sequence generation possible
(though not particularly efficient) for simple typed values is the
presence of the type attribute on xsl:variable. Assuming that:
<xsl:variable name="numbers"
select="'1 2 3'"
type="xs:integer+" />
assigns the sequence (1, 2, 3) to the $numbers variable (this rests on
an unresolved issue, I think, but it looks as though it's a
possibility), I don't see why:
<xsl:variable name="numbers" type="xs:integer+">
<xsl:for-each select="(1 to 3)">
<xsl:value-of select="." />
<xsl:if test="position() != last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:variable>
should not do the same thing.
> 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.
I think you meant:
<xsl:variable name="emps"
select="//employee[some $d in $departments
satisfies @dept = lower-case($d)]"/>
Otherwise I think the existential semantics of = are sufficient?
This example could be handled with a mapping operator:
<xsl:variable name="emps"
select="//employee[@dept = ($departments -> lower-case(.))]" />
In the more general case you could handle it with a function. Assuming
that $departments is a global variable (otherwise it has to be passed
as an argument, but that's not a problem, just makes me have to type
more):
<xsl:function name="my:in-dept">
<xsl:result select="if (not($departments))
then false()
else if (@dept = lower-case($departments[1]))
then true()
else my:in-dept(sublist($departments, 2))" />
</xsl:function>
and:
<xsl:variable name="emps"
select="//employee[my:in-dept()]" />
Keep the examples coming :) My point is that the mapping operator
handles simple cases; user-defined functions can handle the rest; and
if you have the will to make the type attribute on xsl:variable do a
cast, xsl:for-each could also be used to create sequences of simple
typed values.
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list