XSLT如何一次性对所有文本节点应用normalize-space()函数
问题根因
你遇到的多余空白来自源XML元素值首尾附带的换行、缩进字符,直接对xml-to-json()的输出结果调用normalize-space()无效的原因是:该函数会无差别处理整个JSON字符串的所有空白,无法区分JSON语法要求的结构分隔符和值内的多余空白,既无法彻底清理值尾部的残留空白,还存在破坏JSON格式的风险。
全局处理实现
不需要给每个字段单独加normalize-space(),通过预处理JSON映射树的方式可以一次性完成所有文本节点的空白清理,核心逻辑是:
- 先构造不带任何空白处理的原始XML映射结构
- 通过模式化的身份转换遍历该结构,元素、属性等结构节点原样复制,仅对所有文本节点统一执行
normalize-space() - 将清理完成的结构传入
xml-to-json()生成最终结果
完整实现代码如下:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cbl="urn:chanel:names:specification:cbl:schema:xsd:CBLCore1.1.0" xmlns="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="#all" expand-text="yes" > <xsl:output method="text" encoding="UTF-8"/> <!-- 预清理源文档中无业务意义的纯空白节点 --> <xsl:strip-space elements="*"/> <!-- 通用复制模板:原样复制所有结构节点、属性 --> <xsl:template match="node()|@*" mode="cleanWhitespace"> <xsl:copy> <xsl:apply-templates select="node()|@*" mode="cleanWhitespace"/> </xsl:copy> </xsl:template> <!-- 文本节点处理:统一执行空白规范化 --> <xsl:template match="text()" mode="cleanWhitespace"> <xsl:value-of select="normalize-space(.)"/> </xsl:template> <xsl:template match="//root"> <xsl:variable name="rawXml"> <map> <string key="foo">{Foo}</string> <string key="bar">{Bar}</string> <map key="moo"> <map key="voo"> <string key="startDate">{Moo/Voo/StartDate}</string> <string key="endDate">{Moo/Voo/EndDate}</string> </map> </map> </map> </xsl:variable> <!-- 先完成空白清理,再执行JSON转换 --> <xsl:variable name="cleanedXml"> <xsl:apply-templates select="$rawXml" mode="cleanWhitespace"/> </xsl:variable> <xsl:value-of select="xml-to-json($cleanedXml)"/> </xsl:template> </xsl:stylesheet>
特殊场景适配
如果有个别字段需要保留原始空白(比如多行备注、地址类字段),不需要修改全局逻辑,只需要新增一个高优先级的模板,跳过对应字段的normalize处理即可,例如保留key为remark的字段空白:
<xsl:template match="string[@key='remark']/text()" mode="cleanWhitespace" priority="2"> <xsl:value-of select="."/> </xsl:template>
内容的提问来源于stack exchange,提问作者Hayi
相关产品推荐
相关产品推荐

