如何在XML 1.0的XSLT中移除双引号与斜杠?
解决XSLT 1.0中替换/移除双引号和斜杠的问题
看起来你在使用XSLT 1.0处理特殊字符时踩了几个常见的坑,我来帮你拆解问题并给出针对性解决方案:
为什么你的当前代码没生效?
你用到的translate()函数在XSLT 1.0里是字符一一对应替换的逻辑,你的写法存在两个核心问题:
- 字符映射不匹配:你写的
translate(., '"\', '*quote*')中,第二个参数是"和\两个字符,第三个参数是*quote*7个字符。translate会把第一个原字符(")替换成第三个参数的第一个字符(*),第二个原字符(\)替换成第三个参数的第二个字符(q)——这就是你结果里"quotes"变成qquotesq的原因。 - 遗漏了正斜杠
/:你的输入里包含正斜杠,但你没把它加入到要替换的字符列表中,所以它完全没被处理。
另外,输出结果编码变成UTF-16是因为XSLT处理器的默认设置,你可以在<xsl:output>标签里显式指定encoding="utf-8"来修正。
方案1:直接移除双引号、正斜杠、反斜杠
如果只需要移除这些字符,用translate()就足够了,把要移除的字符放在第二个参数,第三个参数留空即可:
<?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="yes" encoding="utf-8"/> <!-- 显式指定编码 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="*/text()"> <!-- 移除"、/、\三种字符 --> <xsl:value-of select="translate(., '"/\', '')"/> </xsl:template> </xsl:stylesheet>
用你的测试输入,会得到如下结果:
<?xml version="1.0" encoding="utf-8"?> <test> I need to remove quotes and slashes from here. </test>
方案2:替换为标记词(如"→quote,/、\→slash)
因为XSLT 1.0没有原生的字符串替换函数(replace()是XSLT 2.0才有的),translate()只能处理单个字符的一一替换,所以要实现把多个字符替换成指定字符串,需要用递归模板:
<?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="yes" encoding="utf-8"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 递归替换特殊字符的模板 --> <xsl:template name="replaceSpecialChars"> <xsl:param name="text"/> <xsl:choose> <!-- 处理双引号 --> <xsl:when test="contains($text, '"')"> <xsl:value-of select="substring-before($text, '"')"/> <xsl:text>*quote*</xsl:text> <xsl:call-template name="replaceSpecialChars"> <xsl:with-param name="text" select="substring-after($text, '"')"/> </xsl:call-template> </xsl:when> <!-- 处理正斜杠 --> <xsl:when test="contains($text, '/')"> <xsl:value-of select="substring-before($text, '/')"/> <xsl:text>*slash*</xsl:text> <xsl:call-template name="replaceSpecialChars"> <xsl:with-param name="text" select="substring-after($text, '/')"/> </xsl:call-template> </xsl:when> <!-- 处理反斜杠 --> <xsl:when test="contains($text, '\')"> <xsl:value-of select="substring-before($text, '\')"/> <xsl:text>*slash*</xsl:text> <xsl:call-template name="replaceSpecialChars"> <xsl:with-param name="text" select="substring-after($text, '\')"/> </xsl:call-template> </xsl:when> <!-- 没有需要替换的字符,输出剩余文本 --> <xsl:otherwise> <xsl:value-of select="$text"/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- 调用替换模板处理文本节点 --> <xsl:template match="*/text()"> <xsl:call-template name="replaceSpecialChars"> <xsl:with-param name="text" select="."/> </xsl:call-template> </xsl:template> </xsl:stylesheet>
用你的测试输入,会得到如下结果:
<?xml version="1.0" encoding="utf-8"?> <test> I need to remove *quote*quotes*quote* and slashes *slash**slash* from here. </test>
内容的提问来源于stack exchange,提问作者Joseph Shea
相关产品推荐
相关产品推荐

