Comparing xslt 2.0 with its predecessor I see a great evolution of the language. There are however parts of language, which are not as good as they could be.
Look at manipulations of sequence of sequence of items. xpath 2.0/xquery 1.0 type system treats type quantifiers separately from type itself. One can declare a variable of type "xs:string", or variable of type of sequence of strings "xs:string*". Unfortunately it's not possible to declare a sequence of sequence of strings "xs:string**", as type can have only one quantifier.
I think this is wrong. People do different tricks to remedy the problem. Typically one builds nodes that contain copy of items of sequences. Clearly this is a heavy way to achieve a simple result, moreover it does not preserve item identity.
In jxom I'm using different solution to store sequence of sequences, namely storing all sequences in one, separated with terminator.
A typical sample is in the java serializer. After building method's parameters I should format them one (compact) or the other (verbose) way depending on decision, which can be made when all parameters are already built.
To see how it's working please look at following xslt:
<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="http://www.nesterovsky-bros.com" exclude-result-prefixes="xs t"> <xsl:output method="xml" indent="yes"/> <!-- Terminator token. --> <xsl:variable name="t:terminator" as="xs:QName" select="xs:QName('t:terminator')"/> <!-- New line. --> <xsl:variable name="t:crlf" as="xs:string" select="' '"/> <xsl:template match="/"> <!-- We need to manipulate a sequence of sequence of tokens. To do this we use $t:terminator to separate sequences. --> <xsl:variable name="short-items" as="item()*"> <xsl:sequence select="t:get-param('int', 'a')"/> <xsl:sequence select="$t:terminator"/> <xsl:sequence select="t:get-param('int', 'b')"/> <xsl:sequence select="$t:terminator"/> <xsl:sequence select="t:get-param('int', 'c')"/> <xsl:sequence select="$t:terminator"/> </xsl:variable> <xsl:variable name="long-items" as="item()*"> <xsl:sequence select="t:get-param('int', 'a')"/> <xsl:sequence select="$t:terminator"/> <xsl:sequence select="t:get-param('int', 'b')"/> <xsl:sequence select="$t:terminator"/> <xsl:sequence select="t:get-param('int', 'c')"/> <xsl:sequence select="$t:terminator"/> <xsl:sequence select="t:get-param('int', 'd')"/> <xsl:sequence select="$t:terminator"/> </xsl:variable> <result> <short> <xsl:value-of select="t:format($short-items)" separator=""/> </short> <long> <xsl:value-of select="t:format($long-items)" separator=""/> </long> </result> </xsl:template> <!-- Returns a sequence of tokens that defines a parameter. $type - parameter type. $name - parameter name. Returns sequence of parameter tokens. --> <xsl:function name="t:get-param" as="item()*"> <xsl:param name="type" as="xs:string"/> <xsl:param name="name" as="xs:string"/> <xsl:sequence select="$type"/> <xsl:sequence select="' '"/> <xsl:sequence select="$name"/> </xsl:function> <!-- Format sequence of sequence of tokens separated with $t:terminator. $tokens - sequence of sequence of tokens to format. Returns formatted sequence of tokens. --> <xsl:function name="t:format" as="item()*"> <xsl:param name="tokens" as="item()*"/> <xsl:variable name="terminators" as="xs:integer+" select="0, index-of($tokens, $t:terminator)"/> <xsl:variable name="count" as="xs:integer" select="count($terminators) - 1"/> <xsl:variable name="verbose" as="xs:boolean" select="$count > 3"/> <xsl:sequence select=" for $i in 1 to $count return ( subsequence ( $tokens, $terminators[$i] + 1, $terminators[$i + 1] - $terminators[$i] - 1 ), if ($i = $count) then () else ( ',', if ($verbose) then $t:crlf else ' ' ) )"/> </xsl:function></xsl:stylesheet>
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u