XSLT仅首字母大写时如何处理McDermott这类特殊姓名例外情况
XSLT首字母大写功能特殊姓名适配方案
核心思路
在原有首字母大写逻辑的基础上,新增特殊姓名前缀匹配规则,遇到Mc、Mac、O'这类常见特殊姓名前缀时,自动将前缀后首个字母转为大写,避免 McDermott 被误转为 Mcdermott 的问题。
修改后完整代码
<xsl:variable name="lowers" select='"abcdefghijklmnopqrstuvwxyz"'/> <xsl:variable name="uppers" select='"ABCDEFGHIJKLMNOPQRSTUVWXYZ"'/> <xsl:variable name="numeric" select="0123456789"/> <xsl:variable name="alpha-numeric" select="concat($lowers,$uppers,$numeric)"/> <!-- 新增特殊姓名前缀配置,可根据实际需求增删,|为分隔符避免误匹配 --> <xsl:variable name="special-prefixes" select="'|Mc|Mac|O''|'"/> <xsl:template name="capitalize"> <xsl:param name="val"/> <xsl:param name="alphanumeric-seen" select="false()"/> <!-- 新增参数:累积已处理完成的字符串,用于匹配特殊前缀 --> <xsl:param name="processed" select="''"/> <xsl:variable name="head" select="substring($val, 1, 1)"/> <xsl:if test="$head"> <xsl:variable name="is-alpha-numeric" select="not(translate($head, $alpha-numeric, ''))"/> <xsl:variable name="tail" select="substring($val, 2)"/> <xsl:choose> <xsl:when test="$is-alpha-numeric"> <xsl:variable name="current-char"> <xsl:choose> <xsl:when test="$alphanumeric-seen"> <!-- 判断已处理字符串后缀是否匹配特殊前缀 --> <xsl:variable name="match-2char-prefix" select="contains($special-prefixes, concat('|', substring($processed, string-length($processed)-1), '|'))"/> <xsl:variable name="match-3char-prefix" select="contains($special-prefixes, concat('|', substring($processed, string-length($processed)-2), '|'))"/> <xsl:choose> <xsl:when test="$match-2char-prefix or $match-3char-prefix"> <!-- 匹配到特殊前缀时,当前字符转大写 --> <xsl:value-of select="translate($head, $lowers, $uppers)"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$head"/> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <!-- 首字符统一转大写 --> <xsl:value-of select="translate($head, $lowers, $uppers)"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <!-- 输出当前字符 --> <xsl:value-of select="$current-char"/> <!-- 递归调用,更新已处理字符串 --> <xsl:call-template name="capitalize"> <xsl:with-param name="val" select="translate($tail, $uppers, $lowers)"/> <xsl:with-param name="alphanumeric-seen" select="true()"/> <xsl:with-param name="processed" select="concat($processed, $current-char)"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$head"/> <xsl:call-template name="capitalize"> <xsl:with-param name="val" select="translate($tail, $uppers, $lowers)"/> <xsl:with-param name="alphanumeric-seen" select="false()"/> <xsl:with-param name="processed" select="concat($processed, $head)"/> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:if> </xsl:template>
代码修改说明
- 新增
$special-prefixes变量,存储所有需要特殊处理的姓名前缀,默认包含Mc、Mac、O'三类常见前缀,可根据业务需求自行增删 - 新增
$processed模板参数,用于累积已经处理完成的字符串,用来匹配特殊前缀 - 调整了非首字母位置的输出逻辑:如果已处理字符串的末尾匹配任意特殊前缀,就将当前字符转为大写后输出,否则保持原逻辑输出
- 支持的特殊场景示例:输入
mcdermott输出McDermott,输入o'neill输出O'Neill,输入macarthur输出MacArthur
内容的提问来源于stack exchange,提问作者Patty
相关产品推荐
相关产品推荐

