XSLT在XML数据转换场景中应用广泛,字符串替换和拼接是日常开发中高频使用的操作,不同版本的XSLT支持的实现方式存在差异,开发者需要根据实际使用的XSLT版本选择合适的方法。

XSLT字符串拼接的实现方法
XSLT 1.0版本的拼接方式
XSLT 1.0没有内置的字符串拼接函数,通常可以通过concat()函数实现,该函数属于XPath 1.0的内置函数,支持传入多个字符串参数,按顺序拼接后返回结果。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="firstName" select="'张'" />
<xsl:variable name="lastName" select="'三'" />
<!-- 拼接两个字符串变量 -->
<result>
<xsl:value-of select="concat($firstName, $lastName)" />
</result>
<!-- 拼接字符串和常量 -->
<result2>
<xsl:value-of select="concat('用户:', $firstName, $lastName, ',年龄:', '25')" />
</result2>
</xsl:template>
</xsl:stylesheet>
上述代码中,concat()函数可以接收任意多个参数,参数可以是字符串常量、XSLT变量或者XPath表达式返回的字符串,最终会按顺序拼接成完整的字符串。
XSLT 2.0及以上版本的拼接方式
XSLT 2.0及以上版本除了支持concat()函数外,还可以使用XPath 2.0引入的字符串连接运算符||,语法更简洁直观。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="part1" select="'Hello'" />
<xsl:variable name="part2" select="'World'" />
<!-- 使用||运算符拼接 -->
<result>
<xsl:value-of select="$part1 || ' ' || $part2" />
</result>
</xsl:template>
</xsl:stylesheet>
XSLT字符串替换的实现方法
XSLT 1.0版本的替换方式
XSLT 1.0没有内置的字符串替换函数,需要开发者自定义递归模板来实现替换逻辑,核心思路是不断查找目标子串的位置,截取前后部分再拼接替换后的内容。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- 自定义字符串替换模板 -->
<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>
<xsl:template match="/">
<xsl:variable name="originalStr" select="'2024-05-20'" />
<result>
<xsl:call-template name="string-replace">
<xsl:with-param name="text" select="$originalStr" />
<xsl:with-param name="search" select="'-'" />
<xsl:with-param name="replace" select="'/'" />
</xsl:call-template>
</result>
</xsl:template>
</xsl:stylesheet>
上述自定义模板通过contains()判断原始字符串是否包含目标子串,使用substring-before()和substring-after()截取对应部分,递归处理直到所有目标子串都被替换。
XSLT 2.0及以上版本的替换方式
XSLT 2.0及以上版本内置了replace()函数,属于XPath 2.0的内置函数,支持直接传入原始字符串、目标子串和替换内容,还可以支持正则表达式匹配替换。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="str1" select="'abc123def456'" />
<!-- 普通子串替换 -->
<result1>
<xsl:value-of select="replace($str1, '123', '***')" />
</result1>
<!-- 正则表达式替换,替换所有数字 -->
<result2>
<xsl:value-of select="replace($str1, 'd+', '#')" />
</result2>
</xsl:template>
</xsl:stylesheet>
replace()函数的第二个参数支持正则表达式,第三个参数是替换后的内容,使用起来比自定义模板更加高效灵活,适合复杂的替换场景。
两种操作的注意事项
- 使用
concat()函数时,如果参数不是字符串类型,XSLT会自动进行类型转换,但是建议提前确认参数类型,避免出现转换异常。 - XSLT 1.0的自定义替换模板只能替换固定的子串,不支持正则表达式,如果需要正则替换,建议升级XSLT版本或者使用扩展函数。
- 处理大量字符串操作时,XSLT 2.0及以上的内置函数性能优于自定义递归模板,优先选择高版本XSLT的内置方法。