- From: Kay, Michael <Michael.Kay@softwareag.com>
- Date: Thu, 8 Jan 2004 19:52:24 +0100
- To: "Roorda, Dirk" <DRoorda@kluwer.nl>, <public-qt-comments@w3.org>
Many thanks for the feedback, and the kind words about Saxon. The working groups will respond in detail, I'll try here to give a provisional response, and also to distill the comments that we need to discuss, some of which belong in different subgroups. I've flagged three points below: A - joint (XPath) B - XSLT C - joint (XPath) > > Performance improvement! > ------------------------ > In XSLT1.0 the code was 160 kB, and on a book of 250 kB it > ran 40 seconds (500MHz). This includes the generations of a > table of contents and several registers. I have completely > rewritten de code in order to exploit the benefits of > XSLT2.0. Now the code is only 100 kB and the execution time > is 20 seconds with identical output. This is excellent news. In general Saxon 7.8 is about 25% faster than 6.5, so the rest of the improvement must be due to new language features. > > Less extensions needed > ---------------------- > I generally enjoyed the improvements of 2.0 over 1.0 very > much. A lot of code I have moved into XPATH2.0 expressions. I > got rid of the use of all extensions, except saxon:evaluate. Also good news. Unless you suggest otherwise, I won't interpret this as a formal comment asking for dynamic XPath evaluation - a feature which the working group has previously decided not to include in the spec this time around. > > Using XSLT2.0 and XPATH2.0 > -------------------------- > 1. No variable declaration in XPATH > While moving code from XSLT to XPATH I encountered one > particular stumbling block: in XPATH you cannot declare > variables in full generality. As you say in your saxon > documentation, XPATH now has variable binding constructs as > for, some and every, but that does not help enough. For > example, if I want to recode something like <xsl:for-each > select="tokenize('1 2 3 4 5')"> > <xsl:variable name="a" as="xs:string" select="my:func1(.)"/> > <xsl:variable name="b" as="xs:integer" select="my:func2(a)"/> > <xsl:variable name="c" as="xs:string *" select="my:func3(a)"/> > <!-- do something useful with $a and $b and $c --> > </xsl:for-each> In XPATH2.0 I am tempted to do something like > this: <xsl:sequence select=" > for $i in tokenize('1 2 3 4 5') return > for $a in my:func1($i) return > for $b in my:func2($a) return > for $c in (my:func3($b)) return > ... > "/> > But the problem here is that $c is sequence valued, and > because sequences cannot be nested, I see no way to bind the > $c of the third for loop to a sequence of strings. That's why > I think XPATH would profit by a define or let construct, like > functional programming languages have, something like define > $x value ( expr ) in expr or more general define $x1 value ( > expr ) $x2 value ( expr ) ... $xn value ( expr ) in expr [Comment A] What you are asking for here is for the XPath "for" expression to be extended to include a larger subset of XQuery's FLWOR expressions, which include a "let" clause that has the functionality you are looking for. The syntax is "let $x := value return expr". This is something that we should consider in the XPath sub-group. > > 2. Text nodes > ------------- > It was not obvious to me how to generate text-nodes. Of the > text comes from a parameter, <xsl:text> does not do it. > Thanks to Michael Kay I know now how to do it: <xsl:function > name="my:text" as="node()?"> > <xsl:param name="text" as="xs:string"/> > <xsl:sequence> > <xsl:value-of select="$text"/> > </xsl:sequence> > </xsl:function> > Note that if $text is empty, no node will be returned! > But I wonder why it is not possible to create text nodes with > <xsl:text> as freely as you create attribute nodes with > <xsl:attribute> and element nodes with <xsl:element> and > namespace nodes with <xsl:namespace>. [Comment B] I think the XSL WG should look again at whether we can make <xsl:text> and <xsl:value-of> synonymous. The current nomenclature will, as you point out, cause people to expect that the instruction for creating text nodes is <xsl:text> rather than <xsl:value-of>, and we should see if we can meet that expectation while retaining backwards compatibility. > > 3. Manipulating the context > --------------------------- > Often I find myself in a situation that I want to repeat a > piece of working code, so I wrap it in a for loop. There are > two options: an XSLT for-each or an XPATH for. When I have > the choice, I take the XPATH version, which has the advantage > that the context node does not change. But when I need to do > things inside the body of the loop that cannot (yet) be done > in XPATH, I am forced to use the XSLT for-each. But then the > context node changes, and this may cause nasty problems. For > example, if I use the function key in the body, it does not > work if the sequence that I selected in the xsl:for-each does > not consist of nodes in the current document. Again, Michael > Kay pointed out that one can say $n/key($key,$value) for a > suitable node $n. This may lead to a more general concept: > allow more access to the stack of contexts that must be > maintained somewhere. It would be nice to be able to specify > in what context an XPATH expression should be evaluated. > Especially in for-each loops, what you really want is to > evaluate XPATH expressions in the parent context, i.e. the > context that was in force just before entering the for-each > loop. For example: current() is the current context node, > current(1) the node that is current in the parent context, > current(2) the node that is current in the grandparent > context. Likewise position(1), position(2) and last(1) and > last(2), etc. Or things like <xsl:value-of select="." context="2"/>. [Comment C] It seems that for complex programming tasks, range variables are needed, while for simple programming tasks, a "context" concept is useful. This means we currently have an awkward mixture of the two. I'm not comfortable with this situation, but I can't see easily how to resolve it. I think a stack of contexts would be quite difficult for some users to cope with: it was offered by Microsoft's WD-xsl dialect and I don't think it was greatly successful. There is a long-standing proposal on the table that a version of the "for" expression (a "simple mapping operator") is needed that binds a context item rather than a range variable; I have also proposed in the past a mechanism that allows a variable to be bound to the context node so that arbitrary joins can be done in a path expression. Adding "let" to XPath, as suggested above, would enable this, though the syntax is not elegant: you would be able to write: //customer[let $c := . return //product[.//customer = $c]] A syntax that looks better in the middle of a path expression might be //customer[$c$ //product[.//customer = $c]] > > 4. Overall impression > --------------------- > I have the feeling that XSLT2.0 is much more of a programming > language than XSLT1.0 was. I am pleased with the more general > datastructures of sequences and with more capabilities of > manipulating nodes, so that you can use node sequences for > general data manipulation. > It's really good to have positive feedback. Thanks! Michael Kay
Received on Thursday, 8 January 2004 13:56:33 UTC