У меня есть XML-документ:
<items> <item> <id>1</id> <title>Title ABC Defg</title> <author>Author Name</author> <description>Description text </description> </item> ... </items>
И я хотел бы сделать ссылку на серфинг и проверку, автор, описание, если содержит фразу
Я не знаю, как сделать это сразу и заказать его по релевантности. Но это не так важно, как поиск слова «Слово» и «слово». Я использовал 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> </p> ?>
Я знаю, что он ищет только заголовки, но проблема в том, что когда я ищу Word, он не может найти слово, и мне бы хотелось получить оба слова: word и Word
Если бы вы могли также помочь мне с «подключением» поиска по названию и описанию автора и заказать его как-то, я бы действительно оценил.
РЕДАКТИРОВАТЬ:
Мне удалось выполнить поиск во всех тегах (не только указано, но для меня это нормально)
поэтому у меня есть код вроде этого:
$query=strtolower(rawurldecode($_GET['s'])); $nodes= $xml->xpath("//item[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'$query')]") // . - all i suppose
я также использую вид проверки $ query
Поэтому вы хотите знать, как выбрать всех дочерних элементов <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)]");
Old: Вы задаете сразу несколько вопросов:
Релевантность не определена. То, что может иметь значение для одного, может быть неактуальным для других, поэтому трудно ответить на эту часть вашего вопроса без конкретного определения того, как релевантность может быть метризована.
Для поиска нечувствительности к регистру повторяющиеся вопросы уже связаны, поэтому вы должны это сделать. Лучше всего надуть в моих глазах:
Но здесь также остается неопределенным, какой случай, нижний и верхний, есть. Вы ничего не указали, поэтому на ваш вопрос нельзя ответить.
Также вы не подтверждаете свой ввод:
$query = $_GET['query']; $nodes = $xml->xpath("//item[contains(title,'$query')]");
Здесь можно ввести xpath с параметром GET. Позаботьтесь, иначе вы вообще не будете искать.