Closed michaelhkay closed 2 years ago
Is this function-name
declaration supposed to be available for any xsl:mode
declaration? What happens with tunnel parameters when xsl:apply-templates
is replaced with a function invocation?
<xsl:mode name="mode2" function-name="my:mode2"/>
<xsl:template match="/">
<xsl:apply-templates mode="mode1">
<xsl:with-param name="foo" select="'bar'" tunnel="yes" as="xs:string"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="/*" mode="mode1">
<xsl:sequence select="my:mode2(node())"/>
</xsl:template>
<xsl:template match="/*/*" mode="mode2">
<xsl:param name="foo" as="xs:string" tunnel="yes"/>
…
</xsl:template>
Is $foo
available when the last template matches?
It would be available if it were invoked with
<xsl:template match="/*" mode="mode1">
<xsl:apply-templates mode="mode2"/>
</xsl:template>
Good question about tunnel parameters. My thinking was no, this function only exposes a subset of the xsl:apply-templates functionality - e.g. no sorting, no with-param, no focus (just the context item as the single function argument).
I like all of these proposals (a, b, and c). The only thing to note is that if xsl:mode/@on-no-match
is intended to be an xpath expression like xsl:sequence/@select
then the example should be false()
instead of return false()
, as return
is only a valid keyword in FLWOR expressions.
MHK response: my thinking was to let on-no-match
take the syntax ( 'shallow-copy' | 'shallow-skip' | ... | 'return' Expr )
where return
is a keyword that indicates that an XPath expression follows. But perhaps that's clumsy.
Coming back to the original motivation for this, it feels like too little benefit to justify the complexity.
An alternative would be for xsl:switch
to allow a match="pattern"
attribute as an alternative (mutually exclusive) to the test
attribute (and perhaps test
should be renamed value
to make the distinction clearer). Because we're moving in the direction of aligning patterns and types, this would give something like XQuery's typeswitch in XSLT. But a switch with match attributes isn't very different from a mode with inline template rules, so is it worth it?
I've also thought about <xsl:if match="pattern">
as an alternative to <xsl:if test="expression">
but I fear the distinction between match="*"
and test="*"
is too subtle.
I haven't found a design for this requirement that I'm comfortable with, so I'm going to drop the feature. I'll delete the draft from the spec.
The draft spec proposes an instruction xsl:match to test whether a given item matches a specified pattern, returning a boolean.
While this fills a gap, it's rather clumsy, especially because instructions that return atomic values typically have to be wrapped in xsl:variable or xsl:function to be useful.
It might be better to try and make xsl:apply-templates work more nicely as a function.
The current
<xsl:match select="N" match="P"/>
is roughly equivalent to<xsl:apply-template mode="test-pattern" select="N"/>
whereCan we improve this?
(a) we could allow
<xsl:mode name="test-pattern" function-name="my:test"/>
so that a function callmy:test(XXX)
is equivalent to the instruction<xsl:apply-templates mode="test-pattern" select="X"/>
: that is, each mode can declare the name of a function whose effect is to apply templates in that mode (with no parameters).(b) we could allow a
select
attribute on xsl:template to provide a quick way of returning the result, avoiding xsl:sequence.(c) we could allow
<xsl:mode on-no-match="return false()"/>
to avoid the fallback template rule.The use-case would then become