Hi y'all
There's something about node-sets I fail to understand.
Say, I have a variable holding a result tree fragment:
<xsl:variable name="rtf-words">
<word>one</word>
<word>two</word>
<word>three</word>
</xsl:variable>
Suppose I want to access the second <word> element:
select="exsl:node-set($rtf-words)/word[2]". That works fine
as long as the stylesheet output is 'simple' xml. But when I
try this in an xhtml-output stylesheet, it doesn't work anymore.
Test stylesheet: (used against any xml doc)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
/>
<xsl:variable name="rtf-words">
<word>one</word>
<word>two</word>
<word>three</word>
</xsl:variable>
<xsl:variable name="rtf-ul">
<ul xmlns="http://www.w3.org/1999/xhtml">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</xsl:variable>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>test node-set</title></head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="/*">
<ul><xsl:apply-templates select="exsl:node-set($rtf-words)/word"
mode="li"/></ul>
<ul><xsl:apply-templates select="exsl:node-set($rtf-ul)/ul/li"
mode="li"/></ul>
</xsl:template>
<xsl:template match="*" mode="li">
<li><xsl:value-of select="."/></li>
</xsl:template>
</xsl:stylesheet>
Output: (saxon 6.5.3)
<ul/>
<ul/>
Expected output:
<ul><li>one</li><li>two</li><li>three</li></ul>
<ul><li>one</li><li>two</li><li>three</li></ul>
The easiest way to solve this, is using "*" instead of the element names, like
select="exsl:node-set($rtf-words)/*"
select="exsl:node-set($rtf-ul)/*/*"
That works, and in most cases it's OK to use "*" because the element names
don't really matter, but I can't understand why:
select="exsl:node-set($rtf-words)/word" and
select="exsl:node-set($rtf-words)/*[self::word]" don't work, but
select="exsl:node-set($rtf-words)/*[name()='word']" does.
It must have something to do with namespaces,
because I found out that adding xmlns="" also helps:
<xsl:variable name="rtf-words">
<word xmlns="">one</word>
<word xmlns="">two</word>
<word xmlns="">three</word>
</xsl:variable>
<xsl:variable name="rtf-ul">
<ul xmlns="">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</xsl:variable>
That does give the expected output. But it puzzles me because I would think
esp. the <ul> element *should* be in xmlns="http://www.w3.org/1999/xhtml"
It also puzzles me that apparently, [self::word] is not the same as
[name()='word']
Any thoughts?
Anton Triest