如何使用php搜索xml文件中的多个关键字并返回包含的标记?

如何使用php搜索xml文件中的多个关键字并返回包含的标记?,php,xml,search,keyword,Php,Xml,Search,Keyword,我有一个这样的xml文件,它存储视频字幕: <videos> <video> <id>1</id> <enSub>Hello Foo! Good morning!</enSub> <cnSub>你好 Foo! 早上好!</cnSub> </video> <video> <id>2

我有一个这样的xml文件,它存储视频字幕:

<videos>
    <video>
        <id>1</id>
        <enSub>Hello Foo! Good morning!</enSub>
        <cnSub>你好 Foo! 早上好!</cnSub>
    </video>
    <video>
        <id>2</id>
        <enSub>Hello Bar! Good afternoon!</enSub>
        <cnSub>你好 Bar! 下午好!</cnSub>
    </video>
</videos>

1.
喂,福!早上好
你好 福!早上好!
2.
你好吧!下午好
你好 酒吧!下午好!
我想通过这个xml搜索某些关键字,就像我在搜索文本区域中输入“hello moning”,搜索结果可以找到id为“1”的视频元素

我猜使用PHPXATH只能在xml文件中找到一个关键字,它必须遍历整个树。我不相信我能写出性能良好的函数

我曾尝试使用外部资源(如谷歌自定义搜索)来搜索我的网站,但结果证明我并没有使用页面来显示每个视频。我将不同的视频id作为参数传递到视频播放页面

我也想到了正则表达式,但不知道如何处理关键字的顺序

所以,有没有搜索引擎,我可以用它来搜索多个关键字,以确定一个视频。我设计它是为了帮助我的用户快速找到观看的视频

我在谷歌上搜索了很多。它真的很慢,有时候我就是无法访问谷歌,在我的中国。我尝试使用“多关键字搜索xml”作为搜索关键字。也许我的英语不够聪明,谷歌无法理解我的意图。我希望你们能理解我的问题


非常感谢你

关于如何实现这一点,请参见下面的示例代码

<?php
$xml = <<<XML
<videos>
    <video>
        <id>1</id>
        <enSub>Hello Foo! Good morning!</enSub>
        <cnSub>你好 Foo! 早上好!</cnSub>
    </video>
    <video>
        <id>2</id>
        <enSub>Hello Bar! Good afternoon!</enSub>
        <cnSub>你好 Bar! 下午好!</cnSub>
    </video>
</videos>
XML;
// Lowercase the XML so we can do a non-case-sensitive search.
$xml = strtolower($xml);
// Create a DOMDocument based on the xml.
$dom = new DOMDocument;
$dom->loadXML($xml);
// Create an xpath based on the dom document so we can search it.
$xpath = new DOMXpath($dom);
// Search for any video tag that contains the text good morning.
$nodes = $xpath->query('//video[contains(.,\'good morning\')]');
// Iterate all nodes
foreach($nodes as $node){
    // find the ID node and print its content.
    var_dump($xpath->query('id',$node)->item(0)->textContent);
}

首先,您的xml很混乱,开始标记和结束标记必须匹配。您可以使用DomDOcument来处理xml

$searchStr ="hello afternoon";
$searchArr = explode(" ",$searchStr);
$result = array();
$xmlData = "<videos>
    <video>
        <id>1</id>
        <enSub>Hello Foo! Good morning!</enSub>
        <cnSub>你好 Foo! 早上好!</cnSub>
    </video>
    <video>
        <id>2</id>
        <enSub>Hello Bar! Good afternoon!</enSub>
        <cnSub>你好 Bar! 下午好!</cnSub>
    </video>
</videos>";

$dom = new DOMDocument();
$dom->loadXML($xmlData);
foreach ($dom->documentElement->childNodes as $node) {
if($node->nodeType==1){
   $enSub = $node->getElementsByTagName('enSub')->Item(0)->nodeValue;
   $cnSub = $node->getElementsByTagName('cnSub')->Item(0)->nodeValue;
   $id = $node->getElementsByTagName('id')->Item(0)->nodeValue;
   foreach($searchArr as $key=>$val){
      $temp = array();
      if( strpos($enSub,$val) != false ){
          $temp[$id] = array(
             'id'=>$id,
             'enSub'=>$enSub,
             'cnSub'=>$cnSub
          );
          $result[$id]=$temp;
      }

   }
 }
}
echo "<pre>";
print_r($result);
$searchStr=“你好,下午好”;
$searchArr=explode(“,$searchStr”);
$result=array();
$xmlData=”
1.
喂,福!早上好!
你好 福!早上好!
2.
你好,酒吧!下午好!
你好 酒吧!下午好!
";
$dom=新的DOMDocument();
$dom->loadXML($xmlData);
foreach($dom->documentElement->childNodes作为$node){
如果($node->nodeType==1){
$enSub=$node->getElementsByTagName('enSub')->Item(0)->nodeValue;
$cnSub=$node->getElementsByTagName('cnSub')->Item(0)->nodeValue;
$id=$node->getElementsByTagName('id')->Item(0)->nodeValue;
foreach($searchArr作为$key=>$val){
$temp=array();
if(strpos($enSub,$val)!=false){
$temp[$id]=数组(
'id'=>$id,
“enSub”=>enSub美元,
“cnSub”=>$cnSub
);
$result[$id]=$temp;
}
}
}
}
回声“;
打印(结果);

您可以找到工作演示

我想您可以使用类似的搜索服务器。它使用Lucene索引任何类型的内容。然后可以通过JSON API查询索引内容

当然,这只有在您不断处理大量数据时才有意义

另一种方法是解析xml并构建一个数组,该数组将子标记中的每个术语作为索引。然后,该值将是一个数组,其中包含在各自标记中具有该术语的电影的ID。 基本上,您正在建立自己的简单数据索引

然后,您可以按如下方式查询索引:


谢谢@诺法尔医学院。我真的很粗心,没有检查我的xml标记。但别担心。在我的项目中,所有标签都是可以的。不相关的,但这里你有一个无麻烦的方法:非常感谢@M感谢您提供了伟大的php沙盒,我从来都不知道!抱歉,无法接受两个答案,但Kyle通过在cnSub和enSub中搜索关键字帮助我确定了视频ID。谢谢@克里斯托夫·格里默·迪特里希。很抱歉,我是php和xml新手,以前没有使用索引。凯尔的回答已经可以做到了。我能理解他的密码。还是谢谢你!没问题,@LukeChen。也许其他人觉得我的答案很有用。既然如此之多的人访问了SO,它可能不是白来的:-)嗨,凯尔!非常感谢!我在php沙箱中测试了您的代码。它真的很好用!我花了一个小时研究了一些我不知道的函数。谢谢我可以问一下这个函数将如何影响我的php托管服务器的性能吗?假设我有1000个用户和1000个用户,他们通过这个功能进行搜索。这会让我的服务器速度变慢吗?我完全不知道表现如何。也许我低估了我的托管php服务器?谢谢你好,凯尔!你能教我contrains()函数中的点“.”是什么意思吗?我查阅了手册,它应该是包含关键字的str吗?另一个问题是我加载了一个xml文件。如何将整个xml文件小写?我应该先加载xml,然后加载$dom->saveXML($dom)吗?谢谢表演不应该是一件大事。如果您担心,为什么不添加1000个视频,然后使用一个应用程序多次访问您的服务器呢。“.”表示当前节点。你可以在这里找到更多信息:()。至于整个xml文件的小写,您可以动态地执行(如我的示例所示),也可以在将文件上载到服务器之前手动执行。谢谢@凯尔,你真的帮了我!
$searchStr ="hello afternoon";
$searchArr = explode(" ",$searchStr);
$result = array();
$xmlData = "<videos>
    <video>
        <id>1</id>
        <enSub>Hello Foo! Good morning!</enSub>
        <cnSub>你好 Foo! 早上好!</cnSub>
    </video>
    <video>
        <id>2</id>
        <enSub>Hello Bar! Good afternoon!</enSub>
        <cnSub>你好 Bar! 下午好!</cnSub>
    </video>
</videos>";

$dom = new DOMDocument();
$dom->loadXML($xmlData);
foreach ($dom->documentElement->childNodes as $node) {
if($node->nodeType==1){
   $enSub = $node->getElementsByTagName('enSub')->Item(0)->nodeValue;
   $cnSub = $node->getElementsByTagName('cnSub')->Item(0)->nodeValue;
   $id = $node->getElementsByTagName('id')->Item(0)->nodeValue;
   foreach($searchArr as $key=>$val){
      $temp = array();
      if( strpos($enSub,$val) != false ){
          $temp[$id] = array(
             'id'=>$id,
             'enSub'=>$enSub,
             'cnSub'=>$cnSub
          );
          $result[$id]=$temp;
      }

   }
 }
}
echo "<pre>";
print_r($result);
<?php

$index = array(
    'Hello' => array(1,3),
    'World' => array(1),
    'Good' => array(2),
    'Morning' => array(2),
    'Vietnam' => array(2,3),
);

$searchTerms = array('Hello', 'World');

$found = null;
foreach($searchTerms as $term){
    if(array_key_exists($term, $index)){
        if(is_null($found)){
            $found = $index[$term];
        } else {
            $found = array_intersect($found, $index[$term]);
        }
    } else {
        $found = array();
        break;
    }
}

print_r($found);