Re: [xsl] Convert text nodes to a single string

Subject: Re: [xsl] Convert text nodes to a single string
From: "Martin Honnen martin.honnen@xxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 9 Mar 2022 13:30:14 -0000
On 09.03.2022 14:26, rick@xxxxxxxxxxxxxx wrote:
>
> Hi All,
>
> I am trying to flatten a messy XHTML file by unwrapping any elements
> that donbt have non-whitespace text nodes. I am trying to return a
> single string from all of the text nodes in an element and see if its
> normalized value is an empty string. Here is my sample input:
>
> <?xml version="1.0" encoding="UTF-8"?>
>
> <root>This has <b>some </b>text.</root>
>
> Here is my stylesheet:
>
> <?xml version="1.0" encoding="UTF-8"?>
>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>
> xmlns:xs="http://www.w3.org/2001/XMLSchema";
>
> xmlns:math="http://www.w3.org/2005/xpath-functions/math";
>
> xmlns:rq="http://www.frameexpert.com/functions";
>
> B B B  exclude-result-prefixes="xs math rq"
>
> B B B B version="3.0" expand-text="yes">
>
> B B B B <xsl:output indent="yes"/>
>
> B B B B <xsl:strip-space elements="td"/>
>
> B B B B <xsl:template match="/root">
>
> <xsl:message>{text()}</xsl:message>
>
> <xsl:message>{count(text())}</xsl:message>
>
> <xsl:message>{count(rq:getStringFromText(text()))}</xsl:message>
>
> B B B B B B B  <xsl:apply-templates/>
>
> B B B  </xsl:template>
>
> B B B B <xsl:function name="rq:getStringFromText" as="xs:string*">
>
> B B B B B B B  <xsl:param name="text-nodes"/>
>
> B B B B B B B  <xsl:for-each select="$text-nodes">
>
> B B B B B B B B B B B  <xsl:value-of select="normalize-space(.)"/>
>
> B B B B B B B  </xsl:for-each>
>
> B B B  </xsl:function>
>
> </xsl:stylesheet>
>
> I expected that this line
>
> <xsl:message>{count(rq:getStringFromText(text()))}</xsl:message>
>
> would return 1, but instead I get 2. Perhaps I need recursion in my
> function. Thank you in advance.
>

I would suggest to use

 B  string-join(.//text())

(XPath 3 string-join I think defaults to the second argument of
string-join as the empty string, I think) or

 B  string-join(.//text(), '')


Then you can test whether e.g. `normalize-space(string-join(.//text(),
'') = ''`

Current Thread