80731312676c352c04426d6f873cc480ab36f102
[homepage.git] / blog / posts / 2007 / 02 / surprising_xslt.mdwn
1 [[meta date="2007-02-02 09:41:45 +0100"]]
2 XSLT's principle of greatest surprise
3 ====
4
5 [Ruby](http://www.ruby-lang.org) and [Python](http://www.python.org) both claim
6 to adhere to the [*principle of least
7 surprise*](http://en.wikipedia.org/wiki/Principle_of_least_surprise), that is:
8 things should work as the human coding in them expects to.  But for today the
9 rants about that are on hold. Still, in the last few days I made up my mind on
10 something related: XSLT adheres to the *principle of greatest surprise*.
11
12 * XPath's data model is based on 4 data types: string, number, boolean,
13 node-set. XSLT adds to it one more: document tree fragment (DTF). When you
14 define a variable (or, better since XSLT is a functional programming language,
15 when you bind a value to a name) you play with a value and a name. No matter the
16 type of the value, that value is automatically casted to a DTF after the
17 binding. Guess you can avoid it?  Wrong. Guess you can cast it back to another
18 data type when needed? Wrong, unless the desired data type is a string. The only
19 other thing you can do with it is output to the final document.
20
21   * Sure, you say, but you have the wonderful [EXSLT
22   extensions](http://exslt.org) which standardized <tt>exsl:node-set()</tt> to
23   cast back a DTF to a node-set (which probably has been previously
24   automatically casted to a DTF by binding it to a variable name). Then, after
25   crossing your fingers in the hope your XSLT processor implements the given
26   extension, guess with me: since a node-set is automatically converted to a DTF
27   with a dummy root node and one children for each node in the node-set (as it
28   is according to XSLT specs), what do you expect <tt>exsl:node-set()</tt> on
29   that node set to return? The original node-set? Wrong. You will have back a
30   node-set with the dummy node as only member. ... enjoy tons of
31   <tt>exsl:node-set($var)//*</tt> expressions in your code
32
33 * Being node-sets the only sequence-like data type in the language, what would
34 you do in case you need to first create a list of strings and then pack them
35 with a join-like function intermixing a textual separator? I personally would go
36 for recursively creating a node-set of strings and then join them. Nice try, but
37 wrong. Adjacent strings in a node-set are automatically joined during
38 processing: bye-bye hope of joining them later. The solution? Wrapper elements
39 around each string in the node-set ...
40
41 * So you have other wonderful extensions like the [set module of
42 EXSLT](http://exslt.org/set/index.html) which implements set-like operations on
43 node-sets. Having seen the following functions: <tt>set:difference()</tt>,
44 <tt>set:intersection()</tt>, ... and knowing that for booleans there are
45 <tt>true()</tt> and <tt>false()</tt>, wouldn't you expect to have
46 <tt>set:empty-node-set()</tt>? I would, but unfortunately the problem is not I
47 was unlucky in guessing the name, there is no such function in the language or
48 in the extensions at all. Everyone in using hacks like <tt>/..</tt>
49
50 * AFAIK the most popular XSLT processor on Unix-like systems is
51 [xsltproc](http://xmlsoft.org/XSLT/xsltproc2.html), which also implements
52 several of the EXSLT extensions. Yay! Of the modules you see listed on the
53 [EXSLT web page](http://exslt.org), what's the one, out of heart, you think you
54 can't live without. . . . .  Regular Expressions!, precisely *the* one xsltproc
55 is *not* implementing. I had to switch to
56 [4xslt](http://sourceforge.net/projects/foursuite/): nice and Pythonish, but not
57 exactly as fast as a lighting bolt.
58
59 /me stops at 50% of my <tt>~/Desktop/xslt-sucks.txt</tt>
60
61 If only [CDuce](http://www.cduce.org) had a syntax I'm able to remember ...
62
63 [[tag lang/english planet/debian fp rant]]
64