Bagaimana saya bisa menggunakan php untuk mencari beberapa kata kunci dalam file xml dan mengembalikan tag yang memuatnya?

Saya memiliki file xml seperti ini, yang menyimpan subtitle video:

<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>

Saya ingin mencari kata kunci tertentu melalui xml ini, seperti saya memasukkan "hello moning" di area teks pencarian, dan hasil pencarian dapat menemukan elemen video dengan id "1".

Saya kira menggunakan php xpath hanya dapat menemukan satu kata kunci dalam file xml, dan harus mengulangi seluruh pohon. Saya tidak yakin bisa menulis fungsi dengan kinerja yang baik.

Saya mencoba menggunakan sumber daya eksternal seperti penelusuran khusus Google untuk menelusuri web saya, tetapi ternyata saya tidak menggunakan halaman untuk menampilkan setiap video. Saya meneruskan id video yang berbeda sebagai parameter ke halaman putar video.

Saya juga memikirkan ekspresi reguler, tetapi tidak tahu cara menangani urutan kata kunci.

Jadi apakah ada mesin pencari yang dapat saya gunakan untuk mencari beberapa kata kunci untuk menemukan sebuah video. Saya merancang ini untuk membantu pengguna saya menemukan video yang ditonton dengan cepat.

Saya banyak mencari di Google. Lambat banget, kadang cuma gak bisa akses google, di tempat saya di China sini. Saya mencoba "beberapa kata kunci pencarian xml" sebagai kata kunci pencarian. Mungkin bahasa Inggris saya tidak cukup pintar agar Google dapat memahami maksud saya. Saya harap kalian di sini memahami pertanyaan saya.

Terima kasih banyak!!


person Luke Chen    schedule 18.12.2013    source sumber
comment
Terima kasih! @Nouphal.M. Saya sangat ceroboh, tidak memeriksa tag xml saya. Tapi jangan khawatir. Di proyek saya, semua tag baik-baik saja.   -  person Luke Chen    schedule 19.12.2013
comment
Tidak terkait, tetapi di sini Anda memiliki pendekatan yang tidak merepotkan: fsockopen.com/php-programming/   -  person Chris Russo    schedule 17.08.2016


Jawaban (3)


Silakan lihat contoh kode saya di bawah ini tentang cara melakukannya.

<?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);
}

-- Sunting

Saya membaca ulang postingan Anda dan sepertinya Anda menggunakan kata kunci dan bukan string. Jika demikian, coba cuplikan ini untuk mengetahui ukurannya:

<?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 an 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);
// Define the search keywords
$searchKeywords = array('good','hello');
// Iterate all of them to make them into valid xpath
$searchKeywords = array_map(
    function($keyword){
        // Replace any single quotes with an escaped single quote.
        $keyword = str_replace('\'','\\\'',$keyword);
        return 'contains(.,\''.$keyword.'\')';
    },
    $searchKeywords
);
// Implode all the keywords using and, you could change this to be
// an"or" condition if you so desire.
$searchKeywords = implode(' and ',$searchKeywords);
// The search keywords now look like contains(.,'good') and contains(.,'hello')
// Search for any video tag that contains the text good morning.
$nodes = $xpath->query('//video['.$searchKeywords.']');
// Iterate all nodes
foreach($nodes as $node){
    // find the ID node and print its content.
    var_dump($xpath->query('id',$node)->item(0)->textContent);
}
person Kyle    schedule 18.12.2013
comment
Hai @Kyle! terima kasih banyak! Saya menguji kode Anda di kotak pasir php. Ini bekerja dengan sangat baik! Saya meluangkan waktu satu jam untuk mempelajari beberapa fungsi yang tidak saya ketahui. Terima kasih! bolehkah saya bertanya bagaimana fungsi ini akan mempengaruhi kinerja server hosting php saya? Katakanlah saya memiliki 1000 pengguna dan 1000 ‹video›s, dan mereka mencari berdasarkan fungsi ini. Apakah ini akan membuat server saya sangat lambat? Saya sama sekali tidak tahu tentang kinerja. mungkin saya meremehkan server php hosting saya? Terima kasih! - person Luke Chen; 19.12.2013
comment
halo @Kyle! Bisakah Anda mengajari saya apa arti titik, '.', dalam fungsi contrains()? Saya mencari manualnya, apakah itu str yang berisi kata kunci? - person Luke Chen; 19.12.2013
comment
Pertanyaan lainnya adalah saya memuat file xml. Bagaimana saya bisa huruf kecil seluruh file xml? Haruskah saya memuat xml terlebih dahulu lalu $dom-›saveXML($dom)? Terima kasih!! - person Luke Chen; 19.12.2013
comment
Kinerja seharusnya tidak menjadi masalah besar. Jika Anda khawatir, mengapa tidak menambahkan 1000 video dan kemudian menggunakan aplikasi untuk mengunjungi server Anda beberapa kali. '.' singkatan dari node saat ini. Anda dapat mengetahui lebih lanjut tentang hal ini di sini: (w3schools.com/xpath/xpath_syntax.asp ). Sedangkan untuk mengecilkan seluruh file xml, Anda dapat melakukannya dengan cepat (seperti yang ditunjukkan dalam contoh saya), atau Anda dapat melakukannya secara manual ke file sebelum mengunggahnya ke server Anda. - person Kyle; 19.12.2013
comment
Terima kasih! @Kyle Anda benar-benar membantu saya! - person Luke Chen; 20.12.2013

Pertama-tama xml Anda berantakan, tag pembuka dan penutup harus cocok. Anda dapat menggunakan DomDOcument untuk memanipulasi 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);

Anda dapat menemukan demo yang berfungsi di sini

person Nouphal.M    schedule 18.12.2013
comment
Terima kasih banyak! @ Nouphal.M Dan terima kasih atas kotak pasir php yang hebat, saya tidak pernah mengetahuinya! Maaf tidak dapat menerima dua jawaban, tapi Kyle membantu saya menentukan ID video dengan mencari kata kunci di cnSub dan enSub. - person Luke Chen; 19.12.2013

Saya kira Anda bisa menggunakan server pencarian seperti ElasticSearch. Ini menggunakan Lucene untuk mengindeks segala jenis konten. Konten yang diindeks kemudian dapat ditanyakan melalui API JSON.

Ini tentu saja hanya masuk akal jika Anda terus-menerus bekerja dengan data dalam jumlah besar.

Pendekatan lainnya adalah dengan mengurai xml dan membuat array yang memiliki setiap istilah dalam sub-tag sebagai indeks. Nilainya kemudian akan berupa larik yang berisi id film yang memiliki istilah tersebut di tagnya masing-masing. Pada dasarnya Anda sedang membangun indeks data sederhana Anda sendiri.

Anda kemudian dapat menanyakan indeks Anda seperti ini:

<?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);

Manfaat utama dari pendekatan ini adalah Anda hanya perlu menelusuri dokumen xml satu kali sambil melakukan pencarian yang cukup cepat. BTW - jika Anda ingin memperlakukan istilah pencarian dengan OR alih-alih AND, Anda dapat menggunakan array_merge dan array_unique alih-alih array_intersect.

Di tengah-tengahnya adalah pendekatan untuk menyiapkan database nyata seperti MySQL dan melakukan pencarian di atas dalam kueri .

Itu sangat tergantung pada apa yang ingin Anda capai.

person Christoph Grimmer-Dietrich    schedule 18.12.2013
comment
Terima kasih! @Christoph Grimmer-Dietrich . maaf saya baru mengenal php dan xml, tidak menggunakan indeks sebelumnya. dan jawaban Kyle sudah bisa melakukan hal tersebut. dan saya dapat memahami kode-kodenya. Terima kasih semua! - person Luke Chen; 19.12.2013
comment
Tidak masalah, @LukeChen. Mungkin orang lain menganggap jawaban saya berguna. Karena SO dikunjungi oleh banyak orang mungkin tidak sia-sia :-) - person Christoph Grimmer-Dietrich; 23.12.2013