XSLT如何将单个元素内容解析为多个变量实现姓名拆分
姓名拆分问题排查与实现方案
多余返回值原因
该问题不属于标准XPath 2.0+规范中tokenize函数的正常行为,触发原因通常为以下两类:
- 使用的XPath解析器存在自定义实现偏差或版本bug:部分非标准/旧版本的
tokenize实现会错误将分隔符匹配规则作为返回值追加到结果序列末尾,而非仅返回分隔符拆分后的内容片段。 - 原始属性值包含特殊内容:可先打印
wd:Payee/@wd:Descriptor的原始值,确认尾部是否存在显式的\s+字符串而非空白字符,该类内容会被识别为普通内容保留在拆分结果中。
姓名拆分最优实现方案
方案1:兼容标准tokenize的实现
先通过normalize-space预处理原始值,清除首尾空白、合并连续空白,再执行拆分,可避免空值或多余字符混入结果:
let $nameParts := tokenize(normalize-space(wd:Payee/@wd:Descriptor), '\s+') return ( $nameParts[1], (: FirstName :) if (count($nameParts) > 2) then string-join($nameParts[position() > 1 and position() < last()], ' ') else '', (: MiddleName 支持多中间名场景 :) $nameParts[last()] (: LastName :) )
该方案可覆盖无中间名、单中间名、多中间名的绝大多数姓名格式场景。
方案2:规避tokenize解析器bug的替代实现
如果确认所用解析器的tokenize函数存在不可修复的bug,可直接用replace函数配合正则提取各字段,无需拆分序列:
- FirstName提取:
replace(normalize-space(wd:Payee/@wd:Descriptor), '^(\S+)\s.*$', '$1') - MiddleName提取:
let $normName := normalize-space(wd:Payee/@wd:Descriptor) return if (count(tokenize($normName, '\s+')) > 2) then replace($normName, '^\S+\s(.*)\s\S+$', '$1') else '' - LastName提取:
replace(normalize-space(wd:Payee/@wd:Descriptor), '^.*\s(\S+)$', '$1')
内容的提问来源于stack exchange,提问作者sircharles
相关产品推荐
相关产品推荐

