【问题标题】:How can I use XPath to perform a case-insensitive search and support non-english characters?如何使用 XPath 执行不区分大小写的搜索并支持非英文字符?
【发布时间】:2010-10-12 04:15:36
【问题描述】:

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

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

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

不仅如此,我还可以使用 ÆØÅæøå 等非英语字符进行搜索,以返回挪威人的姓名。

这怎么可能?

【问题讨论】:

标签: php xml xpath


【解决方案1】:

非英文名称应该不是问题。只需将它们添加到您的 XPath。 (XML 被定义为使用 Unicode)。

至于不区分大小写,...

XPath 1.0 包括以下statement

两个字符串相等当且仅当它们由相同的 UCS 字符序列组成。

因此,即使在本地名称上使用显式谓词也无济于事。

XPath 2 包括映射大小写的函数。例如。 fn:upper-case


附加:使用 XPath 的翻译功能应该允许在 XPath 1 中伪造大小写映射,但输入需要包含您和您的用户将需要的每个大小写代码点:

"test" = translate($inputString, "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ")

【讨论】:

  • 正如我在下面评论的,PHP告诉我找不到函数小写和大写..:/
  • @termserv:XML 总是 unicode。即使您的 XML 文件不是支持 Unicode 的编码,一旦在内存中,这将没有任何区别。
  • @Richard:对您采用“translate()”想法的答案进行投票是公平的。
  • @Tomalak:我忘了,抱歉,但要求投票几乎等于否定了它。
  • 我知道。 ;-) 这也不是我迫切需要它(事实上,如果你只是简单地归功于我而没有投票就可以了)。也许我应该马上做出一个笑脸,因为这不是为了攻击性或其他什么。
【解决方案2】:

另外:

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

您需要从 $query 中删除所有撇号字符以避免破坏您的表达。

在 XPath 2.0 中,您可以将分隔符中使用的引号加倍以将该引号放入字符串文字中,但在 XPath 1.0 中,不可能在字符串中包含分隔符。

【讨论】:

    【解决方案3】:

    在 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 字符串。

    【讨论】:

      【解决方案4】:

      在 XPath 2.0 中,您可以使用lower-case() 函数,它支持 unicode,因此它可以很好地处理非 ASCII 字符。

      contains(lower-case(StopName), lower-case('$query'))
      

      要访问 XPath 2.0,您需要 XSLT 2.0 解析器。例如SAXON。您可以通过 JavaBridge 访问它from PHP

      【讨论】:

      • 这给了我以下错误: - xmlXPathCompOpEval: 找不到函数小写 - 未注册的函数
      • 您可能使用的是 XPath 1.0,此功能仅适用于 XPath 2.0
      • 我使用翻译解决了这个问题,将所有字符转换为小写。感谢您的帮助:)
      猜你喜欢
      • 2016-09-05
      • 2016-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      • 1970-01-01
      • 1970-01-01
      • 2014-04-16
      相关资源
      最近更新 更多