[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Regular expression functions (Was: Re: comments on
David, >> Is it realistic to expect implementations to guarantee to return >> the same thing for any given combination of arguments for a >> particular function? > > Yes for built in xpath functions. they are all (so far) defined so > that is true. Sure - that's because they all either return simple values, nodes from the source tree or a document tree (and as you point out that function has been very tightly defined). > Probably not for externally defined extension functions but the > behaviour of any expression using such function really can't be > specified in Xpath. For example currently given a variable > definition and three references to it, a system is free to evaluate > the variable once and use that value three times, or just to > re-evaluate the expression each time, or something in between. > Mike's given examples on ths list before now of the heuristics saxon > uses to decide which to do. I'm still struggling to pull together all my threads of thought about this. So this is a meander through the issues rather than a carefully thought-out argument. Calls to XSLT extension functions that return new nodes are basically equivalent to references to a variable whose content is the same as calling a template whose body is the body of the function (except with the xsl:result element being removed and its content promoted to the top level of the template). So if you do: <xsl:variable name="foo" select="my:foo('abc')/foo" /> <xsl:function name="my:foo"> <xsl:param name="string" /> <xsl:result> <foo><xsl:value-of select="$string" /></foo> </xsl:result> </xsl:function> It would really be just the same as: <xsl:variable name="bar"> <xsl:call-template name="my:foo"> <xsl:with-param name="string" select="'abc'" /> </xsl:call-template> </xsl:variable> <xsl:variable name="foo" select="$bar/foo" /> <xsl:template name="my:foo"> <xsl:param name="string" /> <foo><xsl:value-of select="$string" /></foo> </xsl:template> The identity of the nodes in result tree fragments never really mattered, but the identity of nodes that you create in a variable *does* matter now. So I don't think that you can do the "re-evaluate three times, then store the value" trick (and very possibly it's not worth doing so anyway because of the differences in effort between creating simple typed values and new node trees). But then the big difference between writing it with a variable and writing it with a function is that it's hard for an XSLT processor to tell when the function call is another reference to the same 'virtual variable'. In the above case, presumably my:foo('abc') should give the same result (the same document) wherever it was called. So if $foo was set globally, and you had $bar set within a template: <xsl:variable name="foo" select="my:foo('abc')" /> <xsl:template match="fred"> <xsl:variable name="bar" select="my:foo('abc')" /> <xsl:if test="$foo == $bar"> ... </xsl:if> </xsl:template> then the test $foo == $bar should be true. But what if my:foo() was defined as: <xsl:function name="my:foo"> <xsl:param name="string" /> <xsl:result> <foo id="{generate-id()}"><xsl:value-of select="$string" /></foo> </xsl:result> </xsl:function> Here the result of the function call depends on the identity of the context node. A processor has to be able to recognise that fact that the result of the function depends on this context node. And that dependency could be hidden deep in some other function within a template call within another stylesheet altogether. Or you might have a function whose use of the context node depended on an argument: <xsl:function name="my:foo"> <xsl:param name="boolean" /> <xsl:result select="if ($boolean) then my:new-element(name(.)) else my:new-element('default')" /> </xsl:function> When you call the function with an argument of false(), you get the "same" node no matter what the context in which the function is called; when you call the function with an argument of true(), you get a different node for each context in which the function is called. [By the way, I'm assuming that the "current date and time" part of the context remains the same throughout a stylesheet - it's stated that it remains the same throughout a "query" in the XPath 1.0 WD, but that's not the same thing, I think.] So where does that leave me... I think that it's very difficult to work out, for any particular user-defined function, when it should always-return-the-same-thing-in-every-context and when it should always-return-the-same-thing-in-a-particular-context. So if you ever want $foo == $foo (where $foo is specified through an expression that calls a user-defined variable) to be optimisable I think the most you can say is that two calls to the same user-defined function, with the same context item, position and size, have to return exactly the same nodes. And of course it's up to the processor to ensure that. You have more freedom with built-in functions, of course, because you know what they're supposed to do and what aspects of the focus they rely on. That enables you to say "within a stylesheet, the document() function must always return the same tree for the same URI" or "within a particular xsl:regexp element, the current-match() function must always return the same tree". Cheers, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|