Reputation: 2081
I have to apply a series of functions to text nodes. At present, it looks like such:
<xsl:function name="local:enhanceTypo" as="text()">
<xsl:param name="s"/>
<xsl:value-of select="
replace(
replace(
translate($s,'<>','‹›')
,'a.a.O.','a. a. O.'
)
,'z.B.','z. B.')
"/>
</xsl:function>
There is a lot more to be done in local:enhanceTypo
and it seems to be funny to make this as a series of nested function calls.
Is there a simple-to-read and -understand way in XSLT2 to sequentially apply a lot of functions to my string?
Upvotes: 2
Views: 87
Reputation: 163458
Certainly chaining variables is one way. I often reuse the same variable name when doing this:
<xsl:variable name="v" select="replace($v, ....)"/>
<xsl:variable name="v" select="replace($v, ....)"/>
<xsl:variable name="v" select="replace($v, ....)"/>
because it's then easy to see what's going on, and to add extra calls into the sequence. I can't speak for other processors, but in Saxon when you do this, the variables are automatically inlined, so it's exactly as if you wrote the deeply nested function call, just easier to read.
If you're into higher-order functions, then with 3.0 there's another way. You can define a sequence of functions like this:
<xsl:variable name="replacements" select="
replace(?, "a", "A"),
replace(?, "b", "B"),
replace(?, "c", "C")"/>
and then you can do a fold-left operation over this sequence:
fold-left($replacements, $string, function ( $in, $f ) { $f($in) })
If your original and replacement strings are in two xs:string* variables $in and $out, then you could instead define the sequence of functions as
<xsl:variable name="replacements" select="
for-each-pair($in, $out, function($i, $o){ replace(?, $i, $o) })"/>
That is, for each pair of input and output strings you create a function that replaces this input by this output, and then you apply the sequence of functions using fold-left.
Fun, eh?
Upvotes: 2