如何用XSLT1.0转义XML实体并清理CDATA及冗余声明?
解决方案:XSLT 1.0 完整转换代码
要同时满足你的两个需求,需要处理双重转义实体替换、移除命名空间、移除XML声明和保留CDATA内容(去掉CDATA标记),以下是完整的XSLT 1.0代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 输出时省略XML声明,缩进格式化 --> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <!-- 递归模板:替换所有 &lt; 为 <,&gt; 为 > --> <xsl:template name="replace-entities"> <xsl:param name="text"/> <xsl:choose> <!-- 先替换 &lt; --> <xsl:when test="contains($text, '&lt;')"> <xsl:value-of select="substring-before($text, '&lt;')"/> <xsl:text><</xsl:text> <xsl:call-template name="replace-entities"> <xsl:with-param name="text" select="substring-after($text, '&lt;')"/> </xsl:call-template> </xsl:when> <!-- 再替换 &gt; --> <xsl:when test="contains($text, '&gt;')"> <xsl:value-of select="substring-before($text, '&gt;')"/> <xsl:text>></xsl:text> <xsl:call-template name="replace-entities"> <xsl:with-param name="text" select="substring-after($text, '&gt;')"/> </xsl:call-template> </xsl:when> <!-- 无匹配则输出原文本 --> <xsl:otherwise> <xsl:value-of select="$text"/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- 匹配所有元素:创建无命名空间的新元素 --> <xsl:template match="*"> <xsl:element name="{local-name()}"> <xsl:apply-templates select="@*|node()"/> </xsl:element> </xsl:template> <!-- 匹配文本节点:调用替换模板处理转义,禁用输出转义让<和>直接显示为标签 --> <xsl:template match="text()"> <xsl:variable name="processed-text"> <xsl:call-template name="replace-entities"> <xsl:with-param name="text" select="."/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$processed-text" disable-output-escaping="yes"/> </xsl:template> <!-- 忽略所有命名空间属性 --> <xsl:template match="@xmlns:*|@*[local-name()='xmlns']"/> <!-- 复制其他节点(注释、处理指令等,如需保留可调整) --> <xsl:template match="@*|comment()|processing-instruction()"> <xsl:copy/> </xsl:template> </xsl:stylesheet>
代码解释
- 移除XML声明:通过
<xsl:output>的omit-xml-declaration="yes"属性直接跳过XML声明输出。 - 移除命名空间:
- 匹配所有元素时,用
local-name()获取不带命名空间的元素名,重新创建无命名空间的元素。 - 专门匹配所有
xmlns相关属性,直接忽略不输出。
- 匹配所有元素时,用
- 替换双重转义实体:
- 用递归模板
replace-entities处理字符串替换(XSLT1.0无原生replace函数,递归是可靠的实现方式),逐个替换&lt;和&gt;。 - 启用
disable-output-escaping="yes",让替换后的<和>直接作为XML标签生效,而非被转义回实体。
- 用递归模板
- 处理CDATA:XSLT1.0会自动解析CDATA块,将其内容作为普通文本节点处理,无需额外操作即可移除CDATA标记并保留内容。
内容的提问来源于stack exchange,提问作者Pawan Pillai
相关产品推荐
相关产品推荐

