Subject: Re: [xsl] Input requested for a good genuine example of the best parts of XSLT 2 From: Rashmi Rubdi <dev_subscriptions@xxxxxxxxx> Date: Wed, 24 Jan 2007 13:55:24 -0800 (PST) |
Hi Abel, XSLT 2.0 uses XPath2.0 which comes with more fuctions and better syntax in comparison with the previous versions. For example 2.0 has an extensive set of date functions, it has a function dedicated to convert upper case to lower case unlike 1.0. Some of us don't have a choice but to stick with XSLT1.0 for a while, until the dependent technologies implement the features of XSLT2.0. Given that XSLT2.0 and XPath2.0 attained W3C recommendation status only a day ago, it will take time before dependent technologies like Xalan upgrade from XSLT1.0 to 2.0 until then, those who use Xalan have to stay with XSLT1.0. Otherwise using the latest version of XSLT is as simple as, using better and easier features. Are you trying to translate everything written in XSLT1.0/XPath1.0 to their 2.0 version? -Rashmi ----- Original Message ---- From: Abel Braaksma <abel.online@xxxxxxxxx> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Sent: Wednesday, January 24, 2007 2:30:50 PM Subject: [xsl] Input requested for a good genuine example of the best parts of XSLT 2 Hi people, During the ongoing discussion about XSLT 2 today and considering/not considering the switch, I thought: why isn't there a nice all-encompassing example that shows the merits of XSLT 2 over XSLT 1? It'll come as no surprise that there's no trivial answer to that, so I figured: why not ask the masses (some people claim that the masses are always right, though that is debatable). The target audience is: XSLT 1 users that would like to know more / understand more of XSLT 2 and are considering the switch. Before we start discussing the template itself, let me throw in some rules: 1. The template must be 100% compliant to the REC 2. There can be no extensions used of whatever kind 3. The template must be rather simple, easy, explainable. 4. It must be run on itself (i.e., no hassle with input files etc) 5. It must show some key concepts, without showing too much detail 6. Does not use functions that call or write resources (xsl:result-document, unparsed-text etc) 7. (optional) it should be runnable on the available xslt 2 processors Apart from (6) and (7), I think it is fairly trivial. I put in (7) so that people that want to see other tools in action (Saxon, Gestalt, Altova) can see them in action (it follows that this means no SA behavior, sorry). I put in (6) to keep the example rather trivial. If users of mentioned and/or missing tools would be so kind as to answer with a one-liner to call the template below from a command line? About the details that should be in the example. I thought of a nice example that can possibly be made infinitely better. Consider it a first draft, and I invite everyone to shoot at it (you may even blast it away ;) This what I put in so far: a) badly designed xml as input (in a variable, see rule 4) b) a micro pipeline c) for-each-group based on value to show groups without Muenchian d) xsl:function for camelcasing a string e) ranges, like "2 to 3" and comparison f) tokenize() and matches() g) for ... in .... return h) next-match i) the use of the 'as' attribute on basic processors The example is rather trivial (it should be, I believe). It takes a list of users of XSLT products, and groups them per product: <james-johnsson>Saxon, c, xslt 2</james-johnsson> <super-troopers>xsltproc, nc, xslt 1</super-troopers> Here: the node name is the user. Then follows a CSV string. The first part is the processor, the second says Compliant or NonCompliant, the third says the language (I am pretty sure the input is not correct, sorry about my lack of knowledge of the compliancy level). The output groups per processor as follows, where some processing is done on the strings and the users are comma-concatenated under <users>: <processor name="Xsltproc"> <level>processor is non-compliant</level> <language>XSLT 1</language> <users>George Williams Geraldson, Super Troopers</users> </processor> I understand this is a rather superficial example. If anybody can make it better, clearer, input is welcome. Keep in mind that it should be kept easy as well as showing the power of XSLT 2 (so it can be used as a showcase). Here's the XSLT so far, any ideas, complaints, suggestions, rewrites, opinions etc are welcome: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; xmlns:xs = "http://www.w3.org/2001/XMLSchema"; xmlns:my = "urn:my" version="2.0" exclude-result-prefixes="#all"> <xsl:output indent="yes" /> <!-- the input, just in a variable ready to use, easy for testing, no need for exslt:node-set() --> <xsl:variable name="preferences"> <james-johnsson>Saxon, c, xslt 2</james-johnsson> <george-williams-geraldson>xsltproc, nc, xslt 1</george-williams-geraldson> <super-troopers>xsltproc, nc, xslt 1</super-troopers> <merry-mirriams>libxslt, nc, xslt 1</merry-mirriams> <john-ronald-reuel-tolkien>saxon, c, xslt 2</john-ronald-reuel-tolkien> <sir-tomald-richards>gestAlt, nc, XSLT 2</sir-tomald-richards> <agatha-kirsten>saxon, c, xslt 2</agatha-kirsten> <mollie-jollie>saxon, c, xslt 2</mollie-jollie> </xsl:variable> <xsl:template match="/" name="main"> <xsl:variable name="micro-pipeline"> <xsl:apply-templates select="$preferences/*" /> </xsl:variable> <!-- group by processor --> <xsl:for-each-group select="$micro-pipeline/processor" group-by="token[1]/upper-case(text())"> <processor name="{my:camel-case(token[1])}" > <xsl:apply-templates select="token[position() = 2 to 3]" /> <users> <!-- join the users in one string and camel case their names --> <xsl:value-of select=" string-join( my:camel-case(current-group()/user) , ', ')" /> </users> </processor> </xsl:for-each-group> </xsl:template> <!-- matches for $preferences nodes --> <xsl:template match="*" priority="0"> <processor> <xsl:next-match /> </processor> </xsl:template> <xsl:template match="*"> <user><xsl:value-of select="local-name(.)" /></user> <xsl:next-match /> </xsl:template> <xsl:template match="text()"> <xsl:for-each select="tokenize(., ',')"> <token><xsl:value-of select="normalize-space(.)" /></token> </xsl:for-each> </xsl:template> <!-- what follows: matches for micro pipeline all matches are case-insensitive, with no need for translate() and trouble with more complex characters --> <xsl:template match="token[matches(., '^c$', 'i')]"> <level>processor is compliant</level> </xsl:template> <xsl:template match="token[matches(., '^nc$', 'i')]"> <level>processor is non-compliant</level> </xsl:template> <xsl:template match="token[matches(., '^xslt', 'i')]"> <language><xsl:value-of select="upper-case(.)" /></language> </xsl:template> <!-- put the nasty bit aside in a function it camel-cases a dashed or space delimited string --> <xsl:function name="my:camel-case" as="xs:string*"> <xsl:param name="string" as="xs:string*"/> <xsl:sequence select="for $s in $string return string-join( for $word in tokenize($s, '-| ') return concat( upper-case(substring($word, 1, 1)), substring($word, 2)) , ' ')" /> </xsl:function> </xsl:stylesheet> Cheers, -- Abel Braaksma http://www.nuntia.nl _____________________________________________________________________________ _______ We won't tell. Get more on shows you hate to love (and love to hate): Yahoo! TV's Guilty Pleasures list. http://tv.yahoo.com/collections/265
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] XSLT to query/output a po, cknell | Thread | Re: [xsl] Input requested for a goo, Abel Braaksma |
RE: [xsl] XSLT to query/output a po, cknell | Date | Re: [xsl] Input requested for a goo, Abel Braaksma |
Month |