如何使用XSL将转义格式特殊字符转换为标准XML格式
XSLT实现多重转义XML字符串还原方案
你遇到的是多重XML实体转义场景,示例中的&amp;lt;本质是<被连续转义2次的结果,还原需要先解码实体转义,再转换为标准XML结构,同时统一属性引号格式,以下是可直接使用的实现方案:
XSLT 2.0及以上版本实现(最简方案)
直接使用内置replace和parse-xml函数完成转换,代码示例:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="no" encoding="UTF-8" /> <!-- 匹配存储转义字符串的节点/文本,替换为实际节点路径即可 --> <xsl:template match="escaped_content_node"> <!-- 第一步:替换所有&为&,还原第一层转义 --> <xsl:variable name="unescaped_str" select="replace(., '&amp;', '&')" /> <!-- 第二步:解析字符串为XML节点,自动修正属性引号格式 --> <xsl:sequence select="parse-xml($unescaped_str)" /> </xsl:template> <!-- 身份模板复制其他不需要修改的内容 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> </xsl:stylesheet>
XSLT 1.0版本实现
XSLT 1.0无内置XML解析函数,使用递归替换模板+禁用输出转义实现:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="no" encoding="UTF-8" /> <!-- 通用递归字符串替换模板 --> <xsl:template name="string-replace"> <xsl:param name="input" /> <xsl:param name="search" /> <xsl:param name="replace" /> <xsl:choose> <xsl:when test="contains($input, $search)"> <xsl:value-of select="substring-before($input, $search)" /> <xsl:value-of select="$replace" /> <xsl:call-template name="string-replace"> <xsl:with-param name="input" select="substring-after($input, $search)" /> <xsl:with-param name="search" select="$search" /> <xsl:with-param name="replace" select="$replace" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$input" /> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- 匹配转义字符串节点,替换为实际节点路径即可 --> <xsl:template match="escaped_content_node"> <!-- 还原第一层转义 --> <xsl:variable name="step1"> <xsl:call-template name="string-replace"> <xsl:with-param name="input" select="." /> <xsl:with-param name="search" select="'&amp;'" /> <xsl:with-param name="replace" select="'&'" /> </xsl:call-template> </xsl:variable> <!-- 还原<转义 --> <xsl:variable name="step2"> <xsl:call-template name="string-replace"> <xsl:with-param name="input" select="$step1" /> <xsl:with-param name="search" select="'&lt;'" /> <xsl:with-param name="replace" select="'<'" /> </xsl:call-template> </xsl:variable> <!-- 还原>转义,兼容示例中缺失&的笔误情况 --> <xsl:variable name="step3"> <xsl:call-template name="string-replace"> <xsl:with-param name="input" select="$step2" /> <xsl:with-param name="search" select="'amp;gt;'" /> <xsl:with-param name="replace" select="'>'" /> </xsl:call-template> </xsl:variable> <!-- 替换属性单引号为双引号 --> <xsl:variable name="step4"> <xsl:call-template name="string-replace"> <xsl:with-param name="input" select="$step3" /> <xsl:with-param name="search" select="'''" /> <xsl:with-param name="replace" select='"' /> </xsl:call-template> </xsl:variable> <!-- 禁用转义输出最终结果 --> <xsl:value-of select="$step4" disable-output-escaping="yes" /> </xsl:template> <!-- 身份模板复制其他不需要修改的内容 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> </xsl:stylesheet>
注意事项
- 若转义层数超过2层,可多次调用实体替换逻辑直到无
&开头的转义实体 - 若存在其他转义实体(如
&quot;、&nbsp;)可按同样规则添加到替换列表中 - XSLT 1.0的
disable-output-escaping属性主流处理器(如Xalan、Saxon 6.x)均兼容
内容的提问来源于stack exchange,提问作者jcalder1969
相关产品推荐
相关产品推荐

