2

我有一个 XML 文档:

     <items>
     <item>
     <id>1</id>
     <title>Title ABC Defg</title>
     <author>Author Name</author>
     <description>Description text </description>
     </item>
     ...
     </items>

我想做一个搜索并检查标题、作者、描述是否包含短语

我不知道如何立即执行并按相关性排序。但它并不像搜索“Word”和“word”那么重要。我使用了php代码:

    <?php
    $xml=simplexml_load_file(file.xml); 
    $query=$_GET['query'];
    $nodes= $xml->xpath("//item[contains(title,'$query')]");

    $count = count($nodes);
    for ($i=1;$i<=$count;$i++){

    $nodes= $xml->xpath("//item[contains(title,'$query')][$i]"); 
    foreach($nodes as $node) {
    $title = $node->title;
    $desc= $node->description;
    $auth= $node->auth;
    $id= $node->id;
    echo "id: $id<br />title: $title<br />author: $auth<br />desc: $desc<p>&nbsp;</p>
    ?>

我知道它只搜索标题,但问题是当我搜索 Word 时它找不到单词,我想同时获得:单词和 Word

如果您还可以帮助我在作者标题和描述中“连接”搜索并以某种方式订购它,我真的会很高兴。

编辑:

我已经设法搜索所有标签(不仅指定,而且对我来说还可以)

所以我有这样的代码:

    $query=strtolower(rawurldecode($_GET['s']));
    $nodes= $xml->xpath("//item[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'$query')]") // . - all i suppose

我也使用 $query 的一种验证

4

1 回答 1

4

所以你想知道,如何选择<items><item>包含使用 xpath 搜索的文本的元素的所有子元素(我不区分大小写,你可以在链接的答案中找到)。首先,所有项目元素:

//items/item

你已经有了。要仅返回包含某些文本的内容,请添加谓词:

//items/item[contains(., 'XYZ')]

如果您只想在<title>子元素中搜索:

//items/item[contains(title, 'XYZ')]

这基本上是你已经拥有的,但是你让你的生活变得不必要地困难:你不需要这样做两次,你可以直接迭代匹配:

$nodes = $xml->xpath("//items/item[contains(title, 'XYZ')]");
foreach ($nodes as $node)
{
    foreach ($node as $name => $prop) {
        printf("%s: %s\n", $name, $prop);
    }
    echo "\n";
}

输出:

id: 3
title: Title XYZ
author: Author Name
description: Description text 

要了解如何将输入转义到 xpath(它是只读的,因此它不像 SQL 注入那样危险),请考虑以下示例:

$query = 'XYZ';
$expression = sprintf("//item[contains(title,'%s')]", $query);
$nodes = $xml->xpath($expression);

它将创建以下表达式:

//item[contains(title,'XYZ')]

但是如果那里有一些单引号会发生什么?它将终止字符串并因此产生错误:

$query = 'd\'oh';

会给:

Warning: SimpleXMLElement::xpath(): Invalid expression in ...

您可以通过在此处进行概述来防止这种情况,特别是为文档分配值并与之进行比较:

$query = 'd\'oh';
$xml['query'] = $query;
$nodes = $xml->xpath("//item[contains(title, /*/@query)]");

旧:你一次问多个问题:

  1. 如何使用不区分大小写的 xpath 进行搜索
  2. 如何找出相关性(因此按相关性对其进行排序)

相关性未定义。对一个人可能相关的内容可能对其他人无关,因此如果没有关于如何衡量相关性的具体定义,很难回答您问题的这一部分。

对于不区分大小写的搜索,已经链接了重复的问题,因此您应该可以这样做。我眼中最好的第一次重复:

但在这里,下限和上限的情况仍然未定义。您还没有指定一件事,因此您的问题无法真正得到回答。

此外,您并没有真正验证您的输入:

$query = $_GET['query'];
$nodes = $xml->xpath("//item[contains(title,'$query')]");

可以使用 GET 参数在此处注入 xpath。小心,否则你根本不会做任何搜索。

于 2012-04-15T13:52:30.910 回答