ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> xsl-list
xsl-list
Re: [xsl] Re: . in for
by Jeni Tennison other posts by this author
Jan 6 2002 4:24PM messages near this date
Re: [xsl] Re: . in for | Re: [xsl] Re: . in for
Hi Dimitre,

> > Absolutely. I suggested a simple mapping operator as a replacement
> > for the more complex for expression that is currently defined in
> > XPath 2.0. I fully recognise the fact that a simple mapping
> > operator gains in simplicity, but loses in completeness - it cannot
> > achieve everything that the for expression can achieve (it can't do
> > joins). I'm sure that you're right that it also cannot achieve
> > everything that a full mapping operator would achieve (perhaps you
> > can give some examples?).
> 
>  Anything that cannot be achieved by a single XPath expression, but
>  can be produced by a template.

Right, so the comment that a simple mapping operator as I suggested
isn't a full mapping operator also applies to the for expression (and
indeed any expression in XPath), since XPath can only do the things
that XPath can do.

>  I hope even in XPath 2.0 / XSLT 2.0 this set is still non-empty?

It depends on whether you view calls to extension functions as being
part of XPath 2.0 or not. You can call/apply templates within
extension functions written in XSLT, so you can construct expressions
that work just like calls to/applying templates.

[snip great explanation of how the functions involved in a functional
composition must be written to take into account the fact they are
part of that composition when working on sequences.]

> > My second question is, whether the above issue is manageable or
> > not, whether implementations could be clever enough to spot where
> > the use of simple mapping operators is equivalent to functional
> > composition, in order to optimise these expressions? Perhaps an
> > implementation could recognise that given:
> > 
> >   $coordinates -> (. * 2)
> >                -> if (position() mod 2) then . + 50 else .
> > 
> > it could compose the two steps on the right hand side of the first
> > -> into a single operation, and use that to give added efficiency?
> 
>  In the general case if an XSLT processor optimizes your previous
>  example, replacing it by a single map with the composition of the
>  expressions, it will yield the wrong result as your detailed example
>  above shows.
> 
>  Anyway, if one designs his algorithm having the single mapping in
>  mind, such an error will not occur -- it only happens when trying to
>  mechanically convert a composition of map-s into a single map, and
>  only if the mapping functions depend on the cardinality of their
>  inputs.
> 
>  A more correct answer is that a function like position() must not be
>  allowed as an argument of a map function/operator. By definition,
>  such a function must have as its ***single*** input only an item of
>  the sequence. position() goes beyond the single item and actually
>  uses the whole sequence as its input.

I see your point about position(). This kinda ties into one of the
points that came out of my reply to Mike's comment about being able to
call user-defined functions from within for expressions, where I
compared:

  <xsl:for-each select="row"> 
    <row num="{position()}"> ...</row>
  </xsl:for-each> 

to:

  <xsl:copy-of
    select="for $i in (1 to count($rows))
            return my:create-row($rows[$i], $i)" /> 

with:

<xsl:function name="my:create-row"> 
  <xsl:param name="row" type="element row" /> 
  <xsl:param name="position" type="xs:integer" /> 
  <xsl:result> 
    <row num="{$position}"> ...</row>
  </xsl:result> 
</xsl:function> 

This illustrates how the value returned by the position() function has
to be replaced by an explicit counter; the same thing goes for the
other information provided by the evaluation context at the point the
function is called - the context size, dynamic variables and so on.
Pure functions only know what they're passed.

Note that replacing the position() function with an explicit counter
means that the $rows sequence has to be traversed several times - once
to count how many items there are in it, and then once for each item
in the $rows sequence in order to retrieve the relevant item for the
function call.

I think that this is likely to be quite inefficient compared to a
single traversal of the $rows sequence, as in xsl:for-each, where
counters are supported by the position() function. So I think that
banning the position() function would be a mistake.

I imagine that a processor would be able to spot situations where the
position() or last() function had been called and only compose the
steps that were composable.
  
> > Fortunately, with the simple mapping operator this works, because
> > in XPath 2.0 individual values are treated exactly the same as
> > single-item sequences.
> 
>  Where did you read it? I read in 2.1.2 (Type conversions) the
>  following:
> 
>  "1. If the required type is anything other than a simple type or a
>  single node, an error is raised."

The second paragraph of Section 6 of the data model WD
(http://www.w3.org/TR/query-datamodel/#sequences) reads:

  "An important characteristic of the data model is that there is no
   distinction between an item (i.e., a node or a simple typed value)
   and a singleton sequence containing that item, i.e., an item is
   equivalent to a singleton sequence containing that item and vice
   versa."

> > I *think* that if you view the series of operations on the right
> > hand side of the simple mapping operator as being functionally
> > composed, then you have the functional composition operator that
> > you're looking for?
> 
>  If it is allowed to perform on a single item a function defined on a
>  sequence, then yes -- because the mapping operator as defined by you
>  is just a functional composition of map-s and a map will (if the
>  assumption that this is allowed is right) operate on a simple value
>  or a node exactly like its argument-function.

Cool :)

Cheers,

Jeni

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


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
Thread:
Dimitre Novatchev
Jeni Tennison
Dimitre Novatchev
Jeni Tennison
Dimitre Novatchev
Michael Kay
Jeni Tennison
Dimitre Novatchev
Jeni Tennison
Dimitre Novatchev
Jeni Tennison
Michael Kay
Dimitre Novatchev
Dimitre Novatchev
Michael Kay

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved