面倒になったので書いてしまった。XHTML以外にも使えるがpre要素だけはよく使うので特別扱いしている。
あらかじめ空白ノードを全て削除しておかなければいけないので使える場面は限られるかも知れない。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xh="http://www.w3.org/1999/xhtml">
<xsl:output omit-xml-declaration="no" version="1.0" method="xml" indent="no" encoding="UTF-8"/>
<xsl:param name="amount" select="' '"/>
<xsl:template match="*[ancestor::*[./@xml:space][1]/@xml:space = 'preserve']
| *[ancestor::xh:pre]" priority="60">
<xsl:element name="{local-name()}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="*[./@xml:space = 'preserve']
| xh:pre" priority="55">
<xsl:call-template name="space"/>
<xsl:element name="{local-name()}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="*[following-sibling::text() or preceding-sibling::text()]" priority="50">
<xsl:element name="{local-name()}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="*[not(child::node())]" priority="45">
<xsl:call-template name="space"/>
<xsl:element name="{local-name()}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="*[child::text()]" priority="40">
<xsl:call-template name="space"/>
<xsl:element name="{local-name()}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="*[not(child::text())]" priority="35">
<xsl:call-template name="space"/>
<xsl:element name="{local-name()}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="@*"/><xsl:text>
</xsl:text>
<xsl:apply-templates/>
<xsl:call-template name="space"/>
</xsl:element><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="comment()">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template name="space">
<xsl:for-each select="ancestor::*">
<xsl:value-of select="$amount"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
http://yudai.arielworks.com/memo/2004/07/14/195507.trackback
末尾に「7 + 0」の計算結果を繋げて下さい。例えば計算結果が「17」の場合、「195507.trackback17」です。これは機械的なトラックバックスパムを防止するための措置です。