Я новичок в XMLReader, и я думаю, что трудно найти учебники / код или что-то передовое, чтобы получить примеры. Мой вопрос в том, как я могу преобразовать код, который у меня есть сейчас, поэтому, если я ищу (через форму), термин jQuery даст мне возможность вывести значение <info></info>
(и позже других элементов) в каждом <name></name>
которое находится в?
Это код, который выводит имена книг.
<?php $reader = new XMLReader(); $reader->open("books.xml"); while ($reader->read()) { switch ($reader->nodeType) { case (XMLREADER::ELEMENT): if ($reader->localName == "name") { $reader->read(); echo $reader->value; break; }}} ?>
xml-файл
<?xml version="1.0" encoding="ISO-8859-1"?> <library> <book isbn="781"> <name>SCJP 1.5</name> <info>Sun Certified Java Programmer book</info> </book> <book isbn="194"> <name>jQuery is Awesome!</name> <info>jQuery Reference Book</info> </book> <book isbn="199"> <name>jQuery 101</name> <info>All you need to know about jQuery</info> </book> </library>
Если вы привязаны к XMLReader для последовательного синтаксического анализа, вы можете создать на нем какой-то парсер.
Один из способов упрощения операции синтаксического анализа состоит в том, чтобы инкапсулировать его в итератор, особенно если вы работаете над последовательностью. Например, с помощью итератора с именем XMLBookIterator
вы можете просто просмотреть все книги во время анализа данных:
$books = new XMLBookIterator($file); foreach($books as $key => $book) { echo 'book (', $key, '):', "\n"; print_r($book); }
Результат может выглядеть следующим образом:
book (0): stdClass Object ( [isbn] => 781 [name] => SCJP 1.5 [info] => Sun Certified Java Programmer book ) book (1): stdClass Object ( [isbn] => 194 [name] => jQuery is Awesome! [info] => jQuery Reference Book ) book (2): stdClass Object ( [isbn] => 199 [name] => jQuery 101 [info] => All you need to know about jQuery )
Тогда остается только отфильтровать книги на основе вашего термина. Это может быть реализовано в FilterIterator
, назовем его BookFilterIterator
:
$filtered = new BookFilterIterator($books, 'jQuery'); foreach($filtered as $key => $book) { echo 'book (', $key, '):', "\n"; print_r($book); }
Затем результат сводится только к соответствующим книгам:
book (1): stdClass Object ( [isbn] => 194 [name] => jQuery is Awesome! [info] => jQuery Reference Book ) book (2): stdClass Object ( [isbn] => 199 [name] => jQuery 101 [info] => All you need to know about jQuery )
Остается только фактический код, который делает это. Это немного дольше, в его сердце – функция next()
внутри итератора, вы найдете анализатор на основе состояния, который читает XML, как вы уже начали с вашего вопроса. Разница в том, что у него есть какое-то состояние, которое помогает заполнить текущую запись книги, которая хранится как частный член класса.
Код , демонстрация
Демо-код использует XML как строку, которая затем преобразуется в псевдо-файл через $file = 'data://text/plain;base64,'.base64_encode($xml);
, Итератор работает с любым именем файла, он просто передается XMLReader
любом случае, поэтому для больших данных используйте файл.
Попробуйте simplexml – это лучше:
<?php $books = simplexml_load_file('books.xml'); $search = 'jquery'; foreach ($books->book as $book) { if (preg_match('/' . preg_quote($search) . '/i', $book->name)) { echo $book->name . ' (' . $book->info . ')<br/>'; } }