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:33:27 -0000
On 09.03.2022 14:30, Martin Honnen martin.honnen@xxxxxx wrote:
>
>
> 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";
>>
>> B B B  xmlns:xs="http://www.w3.org/2001/XMLSchema";
>>
>> B B B  xmlns:math="http://www.w3.org/2005/xpath-functions/math";
>>
>> B B B  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(),
> '') = ''`
>

On the other hand, if you access the string value of an element node
with e.g. data() or directly normalize-space() you don't even need
string-join and can just check `normalize-space() = ''`.

Current Thread