The Caboteria / Tech Web / TechNotes > ProgrammingNotes > XmlNotes / XsltNotes (revision 6)

Reverse Order

Sometimes you want to display a list of items in the reverse order than they appear in the document. http://www.biglist.com/lists/xsl-list/archives/200105/msg00236.html shows how:

    <xsl:apply-templates select="item">
      <xsl:sort select="position()" data-type="number" order="descending" />
    </xsl:apply-templates>

Non-breaking Space

Short answer: use &#160; instead of &nbsp;

Long answer: http://www.dpawson.co.uk/xsl/sect2/nbsp.html

Passthrough

This transform (which I learned from the guys that wrote the most excellent Maverick MVC framework) passes everything through unmolested.

        <xsl:template match="@*|node()">
                <xsl:copy>
                        <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
        </xsl:template>

Links

http://www.jenitennison.com/xslt/ - lots of good XSLT tips
http://www.jenitennison.com/xslt/grouping/index.xml - how to group items in XSLT (can be used to emulate sql's "select distinct" functionality)
http://www.dpawson.co.uk/xsl/sect2/N3328.html - testing whether an element is empty or not (in the many different ways that it can be empty)

Translets vs. Templates

I wanted to see if pre-compiled translets were any faster than Templates so I found some code to compile and run them, and did some micro-benchmarks. Bottom line: translets didn't transform XML faster than Templates, maybe even a little slower. The big win was in initialization but I don't really care about that. Given that translets require Xalan and Templates are built in to Sun's Java I think I'll stick with Templates. While I was at it I tried Java .15 and 1.6 and Saxon 8. I was surprised that Saxon didn't kick the shit out of Xalan - it sure did back in 2003, but now they're in the same ballpark.

using Xalan's "birds" example files, running 5000 times:

first: Templates t = tf.newTemplates(new StreamSource(URI));
second: Transformer transformer = t.newTransformer();
third: transformer = tf.newTransformer(new StreamSource(URI));
fourth: transformer.transform(document, result);

using XSL as input, generating Templates:
before newTemplates: 1189707648447
 after newTemplates: 1189707667564
before newTransformer: 1189707667564
 after newTransformer: 1189707667665
before newTransformer: 1189707667665
 after newTransformer: 1189707689644
before transform: 1189707689645
 after transform: 1189707693274

before newTemplates: 1189707738107
 after newTemplates: 1189707757511
before newTransformer: 1189707757511
 after newTransformer: 1189707757623
before newTransformer: 1189707757624
 after newTransformer: 1189707779782
before transform: 1189707779783
 after transform: 1189707783361

before newTemplates: 1189707955318
 after newTemplates: 1189707974624
before newTransformer: 1189707974624
 after newTransformer: 1189707974747
before newTransformer: 1189707974747
 after newTransformer: 1189707996928
before transform: 1189707996929
 after transform: 1189708000522


using pre-compiled translets:
before newTemplates: 1189707581547
 after newTemplates: 1189707581633
before newTransformer: 1189707581634
 after newTransformer: 1189707581770
before newTransformer: 1189707581770
 after newTransformer: 1189707581905
before transform: 1189707581906
 after transform: 1189707585838

 before newTemplates: 1189707596774
 after newTemplates: 1189707596867
before newTransformer: 1189707596867
 after newTransformer: 1189707597004
before newTransformer: 1189707597004
 after newTransformer: 1189707597131
before transform: 1189707597132
 after transform: 1189707601164

before newTemplates: 1189707611967
 after newTemplates: 1189707612056
before newTransformer: 1189707612056
 after newTransformer: 1189707612193
before newTransformer: 1189707612193
 after newTransformer: 1189707612330
before transform: 1189707612331
 after transform: 1189707616274


using Java 1.5 Templates:

before newTemplates: 1189709259413
 after newTemplates: 1189709266558
before newTransformer: 1189709266559
 after newTransformer: 1189709267926
before newTransformer: 1189709267926
 after newTransformer: 1189709274038
before transform: 1189709274039
 after transform: 1189709280763

before newTemplates: 1189709331211
 after newTemplates: 1189709338562
before newTransformer: 1189709338562
 after newTransformer: 1189709339942
before newTransformer: 1189709339942
 after newTransformer: 1189709346095
before transform: 1189709346096
 after transform: 1189709352755

before newTemplates: 1189709372059
 after newTemplates: 1189709379414
before newTransformer: 1189709379414
 after newTransformer: 1189709380865
before newTransformer: 1189709380865
 after newTransformer: 1189709386942
before transform: 1189709386942
 after transform: 1189709393634


using Java 1.6 Templates:

before newTemplates: 1189709444012
 after newTemplates: 1189709450754
before newTransformer: 1189709450754
 after newTransformer: 1189709452169
before newTransformer: 1189709452170
 after newTransformer: 1189709457757
before transform: 1189709457758
 after transform: 1189709464277

before newTemplates: 1189709482416
 after newTemplates: 1189709489179
before newTransformer: 1189709489179
 after newTransformer: 1189709490581
before newTransformer: 1189709490581
 after newTransformer: 1189709496125
before transform: 1189709496125
 after transform: 1189709502463

before newTemplates: 1189709517385
 after newTemplates: 1189709524028
before newTransformer: 1189709524028
 after newTransformer: 1189709525440
before newTransformer: 1189709525440
 after newTransformer: 1189709531095
before transform: 1189709531095
 after transform: 1189709537325


using saxonb8-j9:

before newTemplates: 1189710098766
 after newTemplates: 1189710103040
before newTransformer: 1189710103040
 after newTransformer: 1189710103055
before newTransformer: 1189710103055
 after newTransformer: 1189710105376
before transform: 1189710105376
 after transform: 1189710111238

before newTemplates: 1189710194556
 after newTemplates: 1189710198665
before newTransformer: 1189710198665
 after newTransformer: 1189710198677
before newTransformer: 1189710198677
 after newTransformer: 1189710201122
before transform: 1189710201122
 after transform: 1189710206944

before newTemplates: 1189710247241
 after newTemplates: 1189710251380
before newTransformer: 1189710251380
 after newTransformer: 1189710251393
before newTransformer: 1189710251393
 after newTransformer: 1189710253711
before transform: 1189710253712
 after transform: 1189710259665

URI Resolution

Contrary to the javadoc, if you set setURIResolver() on the TransformerFactory, your resolver will not be called to resolve URI's provided to the XSLT document() function.

Sun says it's not a bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4459167

The Xalan people say that it is (and they've fixed it in 2.7.1): http://issues.apache.org/jira/browse/XALANJ-2205

In the mean time it appears to work if you also setURIResolver() on the Transformer as well as the factory.

Edit | Attach | Print version | History: r9 < r8 < r7 < r6 < r5 | Backlinks | Raw View | Raw edit | More topic actions...
Copyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding The Caboteria? Send feedback