XSLT 1.0使用translate移除单双引号及无效字符的最优方案
XSLT 1.0 过滤无效字符方案说明
两种现有实现的优缺点
1. 单变量单次translate实现
- 优点:
- 代码简洁,仅需一次函数调用,执行性能最优
- 无效字符统一维护在单个变量中,后续调整过滤规则时修改成本低
- 可读性高,逻辑清晰
- 缺点:
- 需注意变量定义时的引号嵌套问题:如果变量用双引号包裹,内部的双引号需转义为
";如果用单引号包裹,内部的单引号需转义为' - 若特殊字符未用XML实体表示,可能因为XSL文件编码变更导致特殊字符识别异常
- 需注意变量定义时的引号嵌套问题:如果变量用双引号包裹,内部的双引号需转义为
2. 多变量嵌套translate实现
- 优点:
- 避开了单双引号同时出现在一个字符串中的引号嵌套语法问题
- 若需单独控制单/双引号的过滤逻辑,灵活度更高
- 缺点:
- 多次调用
translate函数,存在可忽略的微小性能损耗 - 无效字符规则分散在多个变量中,维护成本更高,代码冗余
- 多次调用
最优方案建议
XSLT 1.0没有原生正则替换功能,针对需求分两种场景处理:
- 仅需移除固定集合的无效字符
translate()就是当前场景的最优实现,没有更高效的原生方案。
规范写法建议:
所有特殊字符优先用XML实体表示,避免编码异常,示例如下:
<xsl:variable name="invalid-chars"><•^"'</xsl:variable> <xsl:value-of select="translate(/Author/Name/FirstName, $invalid-chars, '')" />
- 需要转义字符而非删除(例如将双引号转为
")translate()仅支持一对一字符替换,无法满足多字符转义需求,此时需自定义递归替换模板,示例逻辑如下:
<xsl:template name="string-replace"> <xsl:param name="text" /> <xsl:param name="search" /> <xsl:param name="replace" /> <xsl:choose> <xsl:when test="contains($text, $search)"> <xsl:value-of select="substring-before($text, $search)" /> <xsl:value-of select="$replace" /> <xsl:call-template name="string-replace"> <xsl:with-param name="text" select="substring-after($text, $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="$text" /> </xsl:otherwise> </xsl:choose> </xsl:template>
调用时嵌套调用该模板处理不同需要转义的字符即可。
注意事项
Java内置的Transformer默认使用Xalan的XSLT 1.0实现,完全兼容上述所有写法,你之前的测试输出符合预期,说明基础逻辑没有问题。
内容的提问来源于stack exchange,提问作者user1986244
相关产品推荐
相关产品推荐

