How to recursively join all texts of all preceding siblings?

This is my XML:

<?xml version="1.0"?>

This is my XSL:

<?xml version="1.0"?>
  xmlns:xsl="" version="2.0">
  <xsl:template match="/foo">
    <xsl:apply-templates select="bar" />
  <xsl:template match="bar">
    [<xsl:value-of select="preceding-sibling::text()"/>]

I’m expecting this:

[first x y second]

However, it doesn’t work as expected. Simply put, I’m interested to join all texts (recursively) of all siblings of the current node.

>Solution :

The siblings which you select are not themselves text nodes, therefore you cannot use the text() node test immediately after the preceding-sibiling:: axis. Instead, you must select text descendants of these siblings.

You probably also want to omit whitespace-only texts such as the one between the <b> and <c> elements:

[<xsl:for-each select="preceding-sibling::*//text()
  [normalize-space(.)!='']"> <!-- filter out whitespace-only -->
  <xsl:if test="position()>1">
    <xsl:text> </xsl:text>
  <xsl:value-of select="normalize-space(.)"/>

If you want the texts separated by one space, you must insert that explicitly and remove trailing and leading whitespace with the normalize-space function.

(XSLT 1.0)

Leave a Reply