如何使用XPath执行不区分大小写的搜索并支持非英语字符?

时间:2009-03-09 12:12:43

标签: php xml xpath

我正在使用以下代码在XML文件中执行搜索:

$result = $xml->xpath("//StopPoint[contains(StopName, '$query')]");

其中$ query是搜索查询,StopName是公共汽车站的名称。问题是,它区分大小写。

不仅如此,我还可以搜索ÆØÅæøå等非英语字符来返回挪威名字。

这怎么可能?

4 个答案:

答案 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中,不可能在字符串中包含分隔符。