XSLT 1.0 如何实现非字母数字字符后首个字母自动大写
解决方案
方案1:XSLT 2.0/3.0(推荐,代码简洁)
直接用内置正则替换函数实现,不需要额外扩展:
<xsl:variable name='text' select='"dInEsh sAchdeV kApil Muk O''connel derrick Adrian-merriel james"' /> <xsl:variable name='lowers' select='"abcdefghijklmnopqrstuvwxyz"' /> <xsl:variable name='uppers' select='"ABCDEFGHIJKLMNOPQRSTUVWXYZ"' /> <xsl:template match="/"> <!-- 第一步:先把整个字符串转为首字母大写,其余字符全小写的基础格式 --> <xsl:variable name="normalized-text" select="concat( upper-case(substring($text, 1, 1)), lower-case(substring($text, 2)) )" /> <!-- 第二步:匹配所有非字母数字字符后的小写字母,替换为大写 --> <xsl:value-of select="replace( $normalized-text, '([^a-zA-Z0-9])([a-z])', concat('$1', upper-case('$2')) )" /> </xsl:template>
输出结果完全符合需求:Dinesh Sachdev Kapil Muk O'Connel Derrick Adrian-Merriel James
方案2:XSLT 1.0(兼容旧版本,递归模板实现)
XSLT 1.0没有内置正则替换功能,通过逐字符遍历判断实现,不需要依赖任何扩展函数:
<xsl:variable name='text' select='"dInEsh sAchdeV kApil Muk O''connel derrick Adrian-merriel james"' /> <xsl:variable name='lowers' select='"abcdefghijklmnopqrstuvwxyz"' /> <xsl:variable name='uppers' select='"ABCDEFGHIJKLMNOPQRSTUVWXYZ"' /> <xsl:variable name="alphnums" select="concat($lowers, $uppers, '0123456789')" /> <xsl:template match="/"> <xsl:call-template name="capitalize-after-nonalnum"> <xsl:with-param name="input" select="$text" /> <xsl:with-param name="capitalize-next" select="true()" /> </xsl:call-template> </xsl:template> <xsl:template name="capitalize-after-nonalnum"> <xsl:param name="input" /> <xsl:param name="capitalize-next" /> <xsl:if test="$input != ''"> <xsl:variable name="current-char" select="substring($input, 1, 1)" /> <!-- 判断当前字符是否为字母 --> <xsl:variable name="is-letter" select="contains($lowers, translate($current-char, $uppers, $lowers))" /> <!-- 处理当前字符 --> <xsl:choose> <xsl:when test="$capitalize-next and $is-letter"> <xsl:value-of select="translate($current-char, $lowers, $uppers)" /> </xsl:when> <xsl:when test="$is-letter"> <xsl:value-of select="translate($current-char, $uppers, $lowers)" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="$current-char" /> </xsl:otherwise> </xsl:choose> <!-- 递归处理下一个字符:当前字符是非字母数字的话,下一个字符要大写 --> <xsl:call-template name="capitalize-after-nonalnum"> <xsl:with-param name="input" select="substring($input, 2)" /> <xsl:with-param name="capitalize-next" select="not(contains($alphnums, $current-char))" /> </xsl:call-template> </xsl:if> </xsl:template>
该方案兼容所有XSLT 1.0处理器,输出结果和方案1完全一致。
内容的提问来源于stack exchange,提问作者user12662131
相关产品推荐
相关产品推荐

