XSLT中strip-space失效求助:无法去除short_desc标签内空格
首先,咱们来搞清楚为啥xsl:strip-space没起作用——它的能力其实有明确局限:它只会移除那些完全由空白(空格、换行、制表符)组成的独立文本节点,而不是清理文本节点内部的首尾空白。结合你的场景,核心问题大概率出在这两点:
1. 你可能用了<xsl:copy-of>或者没正确触发模板处理
如果你的根模板(match="/")里是直接用<xsl:copy-of select="."/>复制整个文档,那xsl:strip-space根本不会生效——因为copy-of是直接照搬原始XML的节点树,完全跳过了XSLT的模板规则和空白处理逻辑。
比如这种写法就会导致strip-space失效:
<xsl:template match="/"> <xsl:copy-of select="."/> <!-- 直接复制,跳过模板处理 --> </xsl:template>
2. 目标空格属于文本节点的一部分(而非独立空白节点)
如果<short_desc>的结构是文本内容 + <use_arg_label/> + 末尾空格文本节点,那xsl:strip-space理论上能移除那个纯空白的末尾节点,但如果空格是和前面的文本混在同一个节点里(虽然XML里元素是独立节点,这种情况概率低),strip-space也无能为力。
正确的解决方案
根据你的需求,我们需要保留<use_arg_label/>元素,同时清理<short_desc>内文本的首尾空白,还要确保模板规则正常触发。这里提供两种可行方案:
方案一:结合strip-space和文本节点规范化
这个方案既移除独立空白节点,又统一清理文本节点的首尾空白,还会合并内部的多空格:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 移除short_desc内的纯空白节点 --> <xsl:strip-space elements="short_desc" /> <!-- 处理short_desc元素,复制它并处理子节点 --> <xsl:template match="short_desc"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 针对short_desc下的文本节点,清理首尾空白并合并内部多空格 --> <xsl:template match="short_desc/text()"> <xsl:value-of select="normalize-space(.)"/> </xsl:template> <!-- 默认模板:复制所有其他节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
方案二:精准移除<use_arg_label/>后的空白
如果你只需要移除<use_arg_label/>后面的空格,不想改动其他文本的空白格式,可以用更精确的模板匹配:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 移除short_desc内纯空白节点 --> <xsl:strip-space elements="short_desc" /> <!-- 匹配紧跟在use_arg_label后的纯空白文本节点,直接忽略 --> <xsl:template match="short_desc/text()[preceding-sibling::*[1][local-name()='use_arg_label']][normalize-space(.)='']"/> <!-- 默认复制模板 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键提醒
一定要确保你的根模板(match="/")里是用<xsl:apply-templates/>而不是<xsl:copy-of>,这样才能触发所有的模板规则和空白处理逻辑。比如正确的根模板写法:
<xsl:template match="/"> <xsl:apply-templates/> <!-- 触发子节点的模板处理 --> </xsl:template>
内容的提问来源于stack exchange,提问作者Rajat Khanna




