XSLT 1.0提取HTML文本时单词拼接问题求解
The issue you're facing happens because when you select all text nodes with //body//text() and apply templates directly, XSLT simply concatenates them together without any separators. Text from adjacent elements (like your <u> tags) ends up merged into a single string with no space between words.
Here are two reliable, XSLT 1.0-compatible ways to fix this:
Method 1: Add Spaces Between Text Nodes + Normalize Whitespace
This approach ensures every text node is followed by a space, then cleans up any extra whitespace (including leading/trailing spaces and multiple spaces in a row):
<content name="body_content"> <!-- Collect all text nodes with a trailing space --> <xsl:variable name="text-with-spaces"> <xsl:for-each select="//body//text()"> <!-- Normalize individual text nodes first, then add a separator space --> <xsl:value-of select="concat(normalize-space(.), ' ')"/> </xsl:for-each> </xsl:variable> <!-- Clean up the final string to remove extra whitespace --> <xsl:value-of select="normalize-space($text-with-spaces)"/> </content>
How it works:
normalize-space(.)trims leading/trailing whitespace from individual text nodes and collapses internal spaces (so" Internet Access "becomes"Internet Access").- Adding a trailing space guarantees text from separate elements gets separated by at least one space.
- The final
normalize-space($text-with-spaces)trims leading/trailing spaces and collapses multiple spaces into one, resulting in clean, properly separated text.
Method 2: Template-Based Approach with Conditional Spaces
If you prefer using templates over for-each, you can match text nodes and add a leading space (skipping empty text nodes), then clean up the result:
<!-- Template to handle text nodes inside the body --> <xsl:template match="body//text()"> <!-- Only process non-empty text nodes --> <xsl:if test="normalize-space(.) != ''"> <xsl:value-of select="concat(' ', normalize-space(.))"/> </xsl:if> </xsl:template> <content name="body_content"> <xsl:variable name="prefixed-text"> <xsl:apply-templates select="//body//text()"/> </xsl:variable> <!-- Remove the leading space added by the first text node --> <xsl:value-of select="substring(normalize-space($prefixed-text), 2)"/> </content>
Result for Your Input
Using either method with your sample HTML:
<body> <u>Internet Access</u> <u>Web</u> <u>new cars</u> </body>
You'll get the desired output:
<content name="body_content">Internet Access Web new cars</content>
内容的提问来源于stack exchange,提问作者Edrei Marcelo Ribeiro

