I just (re-)discovered this bit of stupidity in XPath/XSL. The equal operator will demote node-sets, result-trees, etc. into to strings when compared with a string.
Check out this example:
XML File:
<?xml version="1.0" encoding="utf-8"?> <nodes> <node>one fish</node> <node>two fish</node> <node>red fish</node> <node>blue fish</node> </nodes>
XSL File:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
</xsl><xsl :template match="/">
<red -fish>
<xsl:value-of select="//node = 'red fish'"/>
</red>
</xsl>
The output:
<?xml version="1.0"?> <red-fish>true</red>
This is ridiculous. How can you be sure that the equal operator is returning what you want if it silently promotes/demotes things? Reading through the section on booleans in the XPath documentation explains how equality works:
If one object to be compared is a node-set and the other is a string, then the comparison will be true if and only if there is a node in the node-set such that the result of performing the comparison on the string-value of the node and the other string is true.
It’s almost like it was designed by people who don’t program… or maybe a comittee.
This is bad because equality tests will return true in unexpected places. It also means that the designers of XPath could ignore things like set operations. A map(), reduce(), etc. would all be very handy. As would some way to write functions. EXSLT helps with this somewhat, but not much.
Ciao!
You may want to try doing an operation that returns a result tree fragment, which as I recall never gets turned into a string.
@nick:
Sure, but that’s the same thing as turning the node-set into a string first:
string(//node) = 'red fish'At least that’s how I read the Result Tree Fragments section of the XSLT specs.
Ciao!