Change *
to node()
. That will select both elements and text nodes that are children of the <title>
element. Then take out the [1]
since you want all children of <title>
:
<xsl:variable name="full_title"
select="string-join(article/title/node()[not(self::comments)], '')" />
A more reliable way to do it, so that you won't get tripped up if you have multiple levels under <title>
and <comments>
elements occur as grandchildren, would be this:
<xsl:variable name="full_title"
select="string-join(article/title//text()[not(ancestor::comments)], '')" />
Update:
Since you want the variable to hold a string value, and since you're passing it to functions like concat()
and string-length()
which cannot take a sequence of multiple nodes as a first argument, using string-join(..., '')
around the sequence converts it to a string by concatenating the string values of each node.