jQuery XML属性搜索忽略特殊字符(重音)功能求助
问题排查与解决方案
我一眼就看出问题所在了——你对accent_fold函数的使用逻辑完全搞反了!你现在是把整个布尔判断结果传给了去重音函数,而不是对要比较的两个字符串(XML属性值和用户输入文本)分别做去重音处理,这就导致过滤逻辑完全失效了。
核心错误分析
在葡萄牙语环境的判断分支里,你写了这段代码:
var returns = accent_fold(($(this).attr('codigo') || '').toLowerCase().indexOf(texto.toLowerCase()) > -1);
这里($(this).attr('codigo') || '').toLowerCase().indexOf(texto.toLowerCase()) > -1返回的是一个布尔值(true或false),把布尔值传给accent_fold后,函数会将其转为字符串"true"或"false"再处理,最后返回的是原字符串(因为你的accentMap里没有对应字符),而filter方法需要的是布尔值,这就导致过滤逻辑完全不符合预期。
正确的实现思路
要实现忽略特殊字符(重音)的搜索,你需要:
- 对XML属性的
codigo值先做去重音+转小写处理 - 对**用户输入的搜索文本
texto**也做同样的去重音+转小写处理 - 再判断处理后的搜索文本是否存在于处理后的属性值中
另外,你的accentMap只覆盖了部分重音字符,建议补全葡萄牙语中常见的特殊字符(比如ç、ã、õ等),这样搜索覆盖场景更完整。
修正后的完整代码
首先更新accentMap和accent_fold函数:
// 补全葡萄牙语常见重音字符映射 var accentMap = { 'á':'a', 'à':'a', 'ã':'a', 'â':'a', 'é':'e', 'è':'e', 'ê':'e', 'í':'i', 'ì':'i', 'î':'i', 'ó':'o', 'ò':'o', 'õ':'o', 'ô':'o', 'ú':'u', 'ù':'u', 'û':'u', 'ç':'c' }; function accent_fold(s){ if (!s) { return ''; } // 先转字符串,避免非字符串输入 s = String(s); var ret = ''; for (var i = 0; i < s.length; i++) { // 优先取映射值,没有则保留原字符 ret += accentMap[s.charAt(i)] || s.charAt(i); } return ret; }
然后修正pesquisa函数里的过滤逻辑,同时合并重复的代码分支(后面几个else分支逻辑完全一致,可以简化):
function pesquisa() { $("#profissao").empty(); xmlDoc = $.parseXML(xml); var resultado; $xml = $(xmlDoc); var texto = $("#pesq_profissao").val(); if (texto.length > 2) { // 统一处理搜索文本:去重音+转小写 var processedTexto = accent_fold(texto.toLowerCase()); var valor; if( readCookie('googtrans') === '/pt/pt'){ // 葡萄牙语环境:对属性值和搜索文本都做去重音处理 valor = $xml.find('profissao').filter(function() { var codigo = $(this).attr('codigo') || ''; // 处理属性值:去重音+转小写 var processedCodigo = accent_fold(codigo.toLowerCase()); // 判断处理后的文本是否匹配 return processedCodigo.indexOf(processedTexto) > -1; }); } else { // 其他语言环境:保留原大小写不敏感逻辑 valor = $xml.find('profissao').filter(function() { var codigo = ($(this).attr('codigo') || '').toLowerCase(); return codigo.indexOf(texto.toLowerCase()) > -1; }); } resultado = valor; $.each(resultado, function (index, value) { jQuery.fn.reverse = [].reverse; $parents = $(value).parents().reverse(); var new_node = new node($(value)); // 构建路径到根节点 $.each($parents, function (index, value) { var div = document.createElement('div'); var li = document.createElement('li'); $(li).append($(value).attr("descricao")); $(div).addClass("cae_open"); $(div).append(li); $("#profissao").append(div); }); // 构建叶子节点 var div = document.createElement('div'); var a = document.createElement('li'); $(a).append($(value).attr("descricao")); $(a).addClass("transbox"); $(div).addClass("cae_sel"); $(div).append(a); var link = document.createElement('a'); var Sigla = document.createTextNode(new_node.Sigla); link.appendChild(Sigla); $(link).attr("href", new_node.url); $(link).attr('target', '_blank'); a.appendChild(link); $(div).click(function () { parametersValue = jQuery.makeArray($(value).attr("codigo")); FinalizaPesquisa(); }); $("#profissao").append(div); }); if (resultado.length === 0) { var span = document.createElement('span'); $(span).append("Não existem resultados para a sua pesquisa."); $("#profissao").append(span); } } else { buildTree(root); } }
关键修改点说明
- 修正
accent_fold的使用时机:现在是对属性值和搜索文本分别做去重音处理,再进行匹配判断,而不是对判断结果处理。 - 补全重音字符映射:覆盖了葡萄牙语中几乎所有常见的带重音字符,确保搜索更准确。
- 简化代码分支:把重复的过滤逻辑合并到else分支,减少冗余代码。
- 增加类型安全处理:在
accent_fold里把输入转为字符串,避免非字符串值导致的错误。
这样修改后,不管用户输入Técnico、técnico还是Tecnico、tecnico,都能匹配到XML中包含Técnico的profissao节点了。
内容的提问来源于stack exchange,提问作者Aires Menezes
相关产品推荐
相关产品推荐

