我正在使用以下代码在XML文件中执行搜索:
$result = $xml->xpath("//StopPoint[contains(StopName, '$query')]");
其中$ query是搜索查询,StopName是公共汽车站的名称。问题是,它区分大小写。
不仅如此,我还可以搜索ÆØÅæøå等非英语字符来返回挪威名字。
这怎么可能?
答案 0 :(得分:12)
在XPath 1.0中(我相信,PHP SimpleXML可以获得最好的效果),您必须使用translate()
函数从混合大小写输入中生成全小写输出。
为方便起见,我将它包装在这样的函数中:
function findStopPointByName($xml, $query) {
$upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"; // add any characters...
$lower = "abcdefghijklmnopqrstuvwxyzæøå"; // ...that are missing
$arg_stopname = "translate(StopName, '$upper', '$lower')";
$arg_query = "translate('$query', '$upper', '$lower')";
return $xml->xpath("//StopPoint[contains($arg_stopname, $arg_query)");
}
作为一种消毒措施,我要么完全禁止或转义$query
中的单引号,因为如果忽略它们,它们会破坏你的XPath字符串。
答案 1 :(得分:9)
在XPath 2.0中,您可以使用lower-case()
函数,它具有unicode感知功能,因此它可以很好地处理非ASCII字符。
contains(lower-case(StopName), lower-case('$query'))
要访问XPath 2.0,您需要XSLT 2.0解析器。例如SAXON。您可以通过JavaBridge访问它from PHP。
答案 2 :(得分:3)
非英文名称应该不是问题。只需将它们添加到XPath即可。 (XML定义为使用Unicode)。
至于不区分大小写,......
XPath 1.0包含以下statement:
当且仅当两个字符串由相同的UCS字符序列组成时,它们是相等的。
因此,即使在local-name上使用显式谓词也无济于事。
XPath 2包含映射大小写的函数。例如。 fn:upper-case
附加:使用XPath的translate函数应允许在XPath 1中伪造案例映射,但输入需要包含您和用户将需要的每个代码点代码:
"test" = translate($inputString, "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
答案 3 :(得分:0)
另外:
$ xml-> xpath(“// StopPoint [contains(StopName,'$ query')]”);
您需要从$ query中删除任何撇号字符,以避免破坏您的表达。
在XPath 2.0中,您可以将分隔符中使用的引号加倍,将该引号放入字符串文字中,但在XPath 1.0中,不可能在字符串中包含分隔符。