|
|
XSLT's principle of greatest surprise
Ruby and Python both claim to adhere to the
principle
of least surprise, that is: things should work as the
human coding in them expects to. But for today the rants about that
are on hold. Still, in the last few days I made up my mind on
something related: XSLT adheres to the principle of greatest
surprise.
-
XPath's data model is based on 4 data types: string, number,
boolean, node-set. XSLT adds to it one more: document tree fragment
(DTF). When you define a variable (or, better since XSLT is a
functional programming language, when you bind a value to a name)
you play with a value and a name. No matter the type of the value,
that value is automatically casted to a DTF after the binding.
Guess you can avoid it? Wrong. Guess you can cast it back to
another data type when needed? Wrong, unless the desired data type
is a string. The only other thing you can do with it is output to
the final document.
- Sure, you say, but you have the wonderful EXSLT extensions which standardized
exsl:node-set() to cast back a DTF to a node-set (which
probably has been previously automatically casted to a DTF by
binding it to a variable name). Then, after crossing your fingers
in the hope your XSLT processor implements the given extension,
guess with me: since a node-set is automatically converted to a DTF
with a dummy root node and one children for each node in the
node-set (as it is according to XSLT specs), what do you expect
exsl:node-set() on that node set to return? The original
node-set? Wrong. You will have back a node-set with the dummy node
as only member. ... enjoy tons of exsl:node-set($var)//*
expressions in your code
-
Being node-sets the only sequence-like data type in the
language, what would you do in case you need to first create a list
of strings and then pack them with a join-like function intermixing
a textual separator? I personally would go for recursively creating
a node-set of strings and then join them. Nice try, but wrong.
Adjacent strings in a node-set are automatically joined during
processing: bye-bye hope of joining them later. The solution?
Wrapper elements around each string in the node-set ...
-
So you have other wonderful extensions like the set module of EXSLT which
implements set-like operations on node-sets. Having seen the
following functions: set:difference(),
set:intersection(), ... and knowing that for booleans
there are true() and false(), wouldn't you expect
to have set:empty-node-set()? I would, but unfortunately
the problem is not I was unlucky in guessing the name, there is no
such function in the language or in the extensions at all. Everyone
in using hacks like /..
-
AFAIK the most popular XSLT processor on Unix-like systems is
xsltproc,
which also implements several of the EXSLT extensions. Yay! Of the
modules you see listed on the EXSLT web
page, what's the one, out of heart, you think you can't live
without. . . . . Regular Expressions!, precisely the one
xsltproc is not implementing. I had to switch to 4xslt: nice and
Pythonish, but not exactly as fast as a lighting bolt.
/me stops at 50% of my ~/Desktop/xslt-sucks.txt
If only CDuce had a syntax
I'm able to remember ...
|