使用fn:normalize-space()时误删XML标签,求XSLT新手解决方案
解决XSLT使用normalize-space()丢失XML标签的问题
嘿,我来帮你梳理下问题所在~
你遇到的核心问题是:当直接对节点使用normalize-space()时,你其实是在提取该节点的字符串值(也就是把所有子文本节点的内容拼接在一起),这就自然丢掉了XML的元素标签结构。如果没专门处理元素节点,XSLT默认行为会只输出文本内容,标签自然就消失了。
要解决这个问题,我们需要同时保留XML的元素结构,只对文本节点进行空格处理。下面是修正后的思路和代码示例:
修正后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output encoding="UTF-8" indent="yes" method="xml" omit-xml-declaration="no"/> <!-- 匹配所有元素节点:复制元素本身、属性,再递归处理子节点 --> <xsl:template match="*"> <xsl:copy> <xsl:copy-of select="@*"/> <!-- 保留元素的所有属性 --> <xsl:apply-templates/> <!-- 处理子节点(元素、文本等) --> </xsl:copy> </xsl:template> <!-- 专门匹配文本节点:去除前后空格,过滤空文本 --> <xsl:template match="text()"> <xsl:variable name="trimmedText" select="normalize-space(.)"/> <!-- 只输出处理后非空的文本,避免多余空内容 --> <xsl:if test="$trimmedText != ''"> <xsl:value-of select="$trimmedText"/> </xsl:if> </xsl:template> <!-- 匹配根节点,确保整个文档被遍历处理 --> <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet>
代码逻辑说明
- 元素节点模板
match="*":负责保留XML的结构,用<xsl:copy>复制元素本身,<xsl:copy-of>保留元素属性,再通过<xsl:apply-templates>递归处理子节点,这样标签结构就不会丢失。 - 文本节点模板
match="text()":专门处理文本内容,先用normalize-space()去除前后空格,再过滤掉原本全是空格的文本节点,避免输出无效的空内容。 - 根节点模板
match="/":确保整个XML文档从根开始被完整处理。
之前的操作出错,大概率是因为你没有编写处理元素节点的模板,而是直接对父节点使用normalize-space()并输出,导致只提取了文本内容,丢失了标签结构。
内容的提问来源于stack exchange,提问作者Anders Nordlander
相关产品推荐
相关产品推荐

