Парсинг XML с помощью SimpleXML. Для чего нужны XML-парсеры и чем они могут быть полезны Парсеры, работающие по методу дерева

Сейчас мы с вами изучим работу с XML. XML - это формат для обмена данными между сайтами. Он очень похож на HTML, только в XML разрешены свои теги и атрибуты.

Зачем нужен XML при парсинге? Иногда бывает так, что сайт, который вам нужно спарсить, имеет API, с помощью которого можно получить желаемое, особо не напрягаясь. Поэтому сразу совет - перед тем, как парсить сайт, проверьте, нету ли у него API.

Что такое API? Это набор функций, с помощью которых вы можете слать запрос этому сайту и получать нужный ответ. Вот этот ответ чаще всего приходит в формате XML. Поэтому давайте приступим к его изучению.

Работа с XML в PHP

Пусть у вас есть XML. Он может быть в строке, либо хранится в файле или отдаваться по запросу к определенному URL.

Пусть XML хранится в строке. В этом случае из этой строки нужно создать объект с помощью new SimpleXMLElement :

$str = " Коля 25 1000 "; $xml = new SimpleXMLElement($str);

Сейчас у нас в переменной $xml хранится объект с разобранным XML. Обращаясь к свойствам этого объекта можно получать доступ с содержимому тегов XML. Как именно - разберем чуть ниже.

Если же XML хранится в файле или отдается по обращению к URL (что чаще всего и бывает), то следует использовать функцию simplexml_load_file , которая делает тот же объект $xml :

Коля 25 1000

$xml = simplexml_load_file(путь к файлу или урл);

Приемы работы

В примерах ниже наш XML хранится в файле или по URL.

Пусть дан следующий XML:

Коля 25 1000

Давайте получим имя, возраст и зарплату работника:

$xml = simplexml_load_file(путь к файлу или урл); echo $xml->name; //выведет "Коля" echo $xml->age; //выведет 25 echo $xml->salary; //выведет 1000

Как вы видите, у объекта $xml есть свойства, соответствующие тегам.

Вы может обратили внимание, что тег нигде не фигурирует при обращении. Это потому, что он корневой тег. Можно переименовать его, например, на - и ничего не поменяется:

Коля 25 1000

$xml = simplexml_load_file(путь к файлу или урл); echo $xml->name; //выведет "Коля" echo $xml->age; //выведет 25 echo $xml->salary; //выведет 1000

Корневой тег в XML может быть только один, так же, как и тег в обычном HTML.

Давайте чуть модифицируем наш XML:

Коля 25 1000

В этом случае у нас получится цепочка обращений:

$xml = simplexml_load_file(путь к файлу или урл); echo $xml->worker->name; //выведет "Коля" echo $xml->worker->age; //выведет 25 echo $xml->worker->salary; //выведет 1000

Работа с атрибутами

Пусть некоторые данные хранятся в атрибутах:

Номер 1

$xml = simplexml_load_file(путь к файлу или урл); echo $xml->worker["name"]; //выведет "Коля" echo $xml->worker["age"]; //выведет 25 echo $xml->worker["salary"]; //выведет 1000 echo $xml->worker; //выведет "Номер 1"

Теги с дефисами

В XML разрешены теги (и атрибуты) с дефисом. В этом случае обращение к таким тегам происходит так:

Коля Иванов

$xml = simplexml_load_file(путь к файлу или урл); echo $xml->worker->{first-name}; //выведет "Коля" echo $xml->worker->{last-name}; //выведет "Иванов"

Перебор циклом

Пусть теперь у нас не один работник, а несколько. В этом случае мы можем перебрать наш объект с помощью цикла foreach:

Коля 25 1000 Вася 26 2000 Петя 27 3000

$xml = simplexml_load_file(путь к файлу или урл); foreach ($xml as $worker) { echo $worker->name; //выведет "Коля", "Вася", "Петя" }

Из объекта в нормальный массив

Если вам неудобно работать с объектом, вы можете преобразовать его в нормальный массив PHP с помощью следующего хитрого приема:

$xml = simplexml_load_file(путь к файлу или урл); var_dump(json_decode(json_encode($xml), true));

Больше информации

Парсинг на основе sitemap.xml

Зачастую на сайте есть файл sitemap.xml. В этом файле хранятся ссылки на все страницы сайта для удобства индексации их поисковыми системами (индексация - это по сути и есть парсинг сайта яндексом и гуглом).

В общем-то нас мало должно волновать, зачем нужен этот файл, главное, что если он есть - можно не лазить по страницам сайта какими-либо хитрыми методами, а просто воспользоваться этим файлом.

Как проверить наличие этого файла: пусть мы парсим сайт site.ru, тогда обратитесь в браузере к site.ru/sitemap.xml - если что-то увидите, значит он там есть, а если не увидите - то увы.

Если sitemap есть - то в нем содежатся ссылки на все страницы сайта в формате XML. Спокойно забираете этот XML, парсите его, отделяете ссылки на нужные вам страницы любым удобным вам способом (например, анализом URL, который был описан в методе паука).

В итоге вы получаете список ссылок для парсинга, остается только зайти на них и спарсить нужным вам контент.

Подробнее об устройстве sitemap.xml читайте в википедии .

Что вам делать дальше:

Приступайте к решению задач по следующей ссылке: задачи к уроку .

Когда все решите - переходите к изучению новой темы.

Сейчас мы с вами изучим работу с XML. XML - это формат для обмена данными между сайтами. Он очень похож на HTML, только в XML разрешены свои теги и атрибуты.

Зачем нужен XML при парсинге? Иногда бывает так, что сайт, который вам нужно спарсить, имеет API, с помощью которого можно получить желаемое, особо не напрягаясь. Поэтому сразу совет - перед тем, как парсить сайт, проверьте, нету ли у него API.

Что такое API? Это набор функций, с помощью которых вы можете слать запрос этому сайту и получать нужный ответ. Вот этот ответ чаще всего приходит в формате XML. Поэтому давайте приступим к его изучению.

Работа с XML в PHP

Пусть у вас есть XML. Он может быть в строке, либо хранится в файле или отдаваться по запросу к определенному URL.

Пусть XML хранится в строке. В этом случае из этой строки нужно создать объект с помощью new SimpleXMLElement :

$str = " Коля 25 1000 "; $xml = new SimpleXMLElement($str);

Сейчас у нас в переменной $xml хранится объект с разобранным XML. Обращаясь к свойствам этого объекта можно получать доступ с содержимому тегов XML. Как именно - разберем чуть ниже.

Если же XML хранится в файле или отдается по обращению к URL (что чаще всего и бывает), то следует использовать функцию simplexml_load_file , которая делает тот же объект $xml :

Коля 25 1000

$xml = simplexml_load_file(путь к файлу или урл);

Приемы работы

В примерах ниже наш XML хранится в файле или по URL.

Пусть дан следующий XML:

Коля 25 1000

Давайте получим имя, возраст и зарплату работника:

$xml = simplexml_load_file(путь к файлу или урл); echo $xml->name; //выведет "Коля" echo $xml->age; //выведет 25 echo $xml->salary; //выведет 1000

Как вы видите, у объекта $xml есть свойства, соответствующие тегам.

Вы может обратили внимание, что тег нигде не фигурирует при обращении. Это потому, что он корневой тег. Можно переименовать его, например, на - и ничего не поменяется:

Коля 25 1000

$xml = simplexml_load_file(путь к файлу или урл); echo $xml->name; //выведет "Коля" echo $xml->age; //выведет 25 echo $xml->salary; //выведет 1000

Корневой тег в XML может быть только один, так же, как и тег в обычном HTML.

Давайте чуть модифицируем наш XML:

Коля 25 1000

В этом случае у нас получится цепочка обращений:

$xml = simplexml_load_file(путь к файлу или урл); echo $xml->worker->name; //выведет "Коля" echo $xml->worker->age; //выведет 25 echo $xml->worker->salary; //выведет 1000

Работа с атрибутами

Пусть некоторые данные хранятся в атрибутах:

Номер 1

$xml = simplexml_load_file(путь к файлу или урл); echo $xml->worker["name"]; //выведет "Коля" echo $xml->worker["age"]; //выведет 25 echo $xml->worker["salary"]; //выведет 1000 echo $xml->worker; //выведет "Номер 1"

Теги с дефисами

В XML разрешены теги (и атрибуты) с дефисом. В этом случае обращение к таким тегам происходит так:

Коля Иванов

$xml = simplexml_load_file(путь к файлу или урл); echo $xml->worker->{first-name}; //выведет "Коля" echo $xml->worker->{last-name}; //выведет "Иванов"

Перебор циклом

Пусть теперь у нас не один работник, а несколько. В этом случае мы можем перебрать наш объект с помощью цикла foreach:

Коля 25 1000 Вася 26 2000 Петя 27 3000

$xml = simplexml_load_file(путь к файлу или урл); foreach ($xml as $worker) { echo $worker->name; //выведет "Коля", "Вася", "Петя" }

Из объекта в нормальный массив

Если вам неудобно работать с объектом, вы можете преобразовать его в нормальный массив PHP с помощью следующего хитрого приема:

$xml = simplexml_load_file(путь к файлу или урл); var_dump(json_decode(json_encode($xml), true));

Больше информации

Парсинг на основе sitemap.xml

Зачастую на сайте есть файл sitemap.xml. В этом файле хранятся ссылки на все страницы сайта для удобства индексации их поисковыми системами (индексация - это по сути и есть парсинг сайта яндексом и гуглом).

В общем-то нас мало должно волновать, зачем нужен этот файл, главное, что если он есть - можно не лазить по страницам сайта какими-либо хитрыми методами, а просто воспользоваться этим файлом.

Как проверить наличие этого файла: пусть мы парсим сайт site.ru, тогда обратитесь в браузере к site.ru/sitemap.xml - если что-то увидите, значит он там есть, а если не увидите - то увы.

Если sitemap есть - то в нем содежатся ссылки на все страницы сайта в формате XML. Спокойно забираете этот XML, парсите его, отделяете ссылки на нужные вам страницы любым удобным вам способом (например, анализом URL, который был описан в методе паука).

В итоге вы получаете список ссылок для парсинга, остается только зайти на них и спарсить нужным вам контент.

Подробнее об устройстве sitemap.xml читайте в википедии .

Что вам делать дальше:

Приступайте к решению задач по следующей ссылке: задачи к уроку .

Когда все решите - переходите к изучению новой темы.

На днях я начал перерабатывать свою систему внутренней отчётности фирмы, об общем устройстве которой писал не так давно. Не кривя душой, скажу, что вырос над собой в плане PHP, и, как следствие, понял, что алгоритм системы достаточно кривой для того, чтобы я его переписал.

До этого XML-документ парсился с помощью функций, которые заимствованы из PHP 4-й версии. Однако PHP5 подарил миру очень удобную вещь под названием SimpleXML. О том, как же с ним работать, и пойдёт речь сегодня.

Стоит начать с того, что SimpleXML — это отдельный подключаемый модуль, а потому его надо заранее подключить на используемом сервере.

Теперь мы можем работать!

Для того, чтобы обработать документ, используем функцию simplexml_load_file(). В качестве параметра ей передается адрес файла в формате eXtended Markup Language (XML — Ваш К.О.).

Прелесть данной функции в том, что ей совершенно спокойно можно передать файл с любого сервера. Таким образом, у нас появляется возможность обрабатывать внешние xml-выгрузки (к примеру, Яндекс-XML или сторонние RSS-ленты).

На выходе функция выдает массив. Подводный камень, с которым столкнулся я, в том, что XML может иметь корявую структуру, а потому советую для начала провести образную трассировку и вывести массив, чтобы понять, как же функция его обработала. После этого можно приступать к обработке полученных данных.

Для примера я возьму простенькую конструкцию отсюда :


>
>
> PHP: Появление Парсера>
>
>
> Ms. Coder>
> Onlivia Actora>
>
>
> Mr. Coder>
> El ActÓ r>
>
> > Mr. Parser> > John Doe> > >
>
Таким образом, это язык. Это все равно язык программирования. Или
это скриптовый язык? Все раскрывается в этом документальном фильме,
похожем на фильм ужасов.
>
>
> PHP решает все мои задачи в web>
>
7>
5>
PG> >
>

Пусть это будет файл export.xml, который лежит прямо в корне моего сервера вместе с обрабатывающим его скриптом.
Массив строится в соответствии со структурой DOM-элементов в XML-документе. Обработка начинается от корня. Для того, чтобы получить имя Ms. Coder, мы должны выстроить следующий путь: $xml->movies->movie->characters->character->name.
Обращаю внимание, что мы выбираем конкретное значение. Отсюда и берется запись такого рода character — не забываем, что мы работаем с массивом!

Как и любой массив, наши данные можно обработать при помощи цикла foreach. Код будет такой:

$xml = simplexml_load_file ("export.xml" ) ; //выгрузили файл
$ttl = $xml -> movies -> movie -> title ; //получили заголовок. он один, так что или другое значение ставить не надо

foreach ($xml -> movies -> movie -> caracters as $crc ) // а теперь поработаем в динамике
{
//выведем имена героев
$name = $crc -> caracter -> name ;
echo ("$name
"
) ;
}

Такой код положит в переменную $ttl текст «PHP: Появление Парсера», а затем выведет построчно на экран имена героев
Ms. Coder, Mr. Coder, Mr. Parser.

Xml парсер - это программа, которая извлекает из исходного файла xml формата данные и сохраняет или использует для последующих действий.

Почему нужны xml парсеры?

В первую очередь потому что сам по себе формат xml популярный среди компьютерных стандартов. XML файл выглядит так:

т.е. по сути есть теги, есть какие-то правила какие теги должны следовать друг за другом.

Причина популярности xml файлов заключается в том, что он хорошо читаем человеком. И то, что его относительно легко обрабатывать в программах.

Минусы xml-файлов.

Минусом является в первую очередь большое количество места на диске, которое занимают эти данные. Ввиду того, что теги, которые постоянно повторяются, при больших объемах данных, занимаю относительно много мегабайт, которые просто необходимо скачивать из источника, а потом и обрабатывать. Есть ли альтернативы? Есть, конечно, но все равно, парсеры xml и xml сегодня один из самых простых и надежных и технологически популярных форматов.

Как пишутся XML парсеры?

Парсеры пишутся на языках программирования. Как говорится пишутся на всех, но не некоторых больше. Следует понимать, что есть языки программирования, в которых есть уже встроенные библиотеки для парсинга xml файлов. Но в любом случае даже если библиотеки нет, можно всегда найти подходящую библиотеку для этого дела и использовать ее для извлечения данных из файла.

Глобально есть 2 разных подхода как парсить xml файлы.

Первый - это загружать xml файл полностью в память ну и дальше делать манипуляции по извлечению данных.

Второй - это потоковый вариант. В этом случае в языке программирования определяется определенные теги на которые нужно реагировать функциям создаваемого xml парсера и уже программист сам решает, что нужно делать в случае обнаружения того или иного тега.

Плюсом первого подхода является скорость. Сразу все загрузил файл, потом быстро пробежался в памяти нашел, что нужно и самое главное программировать легко. но Минус есть и очень важный - это

большой объем памяти требуется для работы. Иногда, я бы даже сказал часто бывает так, что просто невозможно обработать и распарсить xml файл, т.е. создать xml парсер, чтобы работал по первому способу корректно. Почему так? Ну, например, ограничение для 32 битных приложений под виндой позволяет программе максимально занимать 2 гигабайта памяти - больше нельзя.

Однако программировать по поточному варианту сложно. Сложность при достаточно серьезном извлечении вырастает в разы, что соответственно сказывается и на сроках и на бюджете.

Валидность xml файлов и парсеров.

Все было бы с xml файлами и xml парсерами хорошо, но вот есть проблема. Ввиду того, что создать xml файл может "любой школьник", а в реальности так и есть (потому что очень много кода пишется школьниками, то появляются невалидные файлы, т.е. некорректные. Что это значит и чем это чревато? Самая большая проблема, это то, что просто невозможно иногда корректно распарсить невалидный файл. Например у него теги не закрываются как следовало бы ожидать по стандарту или например кодировка задана неверно. Другая проблема заключается, что если например делаешь парсер на.net то, можно создать так называемые врапперы, и самое обидное бывает, что вот сделаешь такой враппер, а потом считываешь им файл, который "школьник" создал, а файл невалидный и его прочитать невозможно. Поэтому приходиться изгаляться и прибегать к весьма и весьма непопулярным вариантам парсинга таких файлов. А все из=за того, что многие создают xml файлы без использования стандартных библиотек и с полным отвращениям ко всем стандартам xml файлов. Заказчикам это сложно объяснить. Они ждут результат - xml парсер, который преобразует данные из оригинального файла в другой формат.

Как создавать xml парсеры (первый вариант)

Есть такой язык запросов к XML данным как Xpath. Язык этот имеет две редакции, углубляться не будем в особенности каждой версии. Лучше представление про этот язык покажут примеры того как использовать его для извлечения данных. Например.

//div[@class="supcat guru"]/a

что делает этот запрос. Он забирает все а тэги, которые имею хреф, содержаший текст catalog.xml?hid= и этот а тэг должен быть чайлдом дива у которого класс равен supcat guru.

Да, на первый раз может быть и не достаточно понятно, но, все же разобраться можно если захотите. Отправная точка для меня это http://ru.wikipedia.org/wiki/XPath и вам советую.

XML для PHP-разработчиков

Часть 2. Расширенные методы парсинга XML

Методы синтаксического анализа объемных или сложных XML-документов в PHP5

Серия контента:

В PHP5 увеличено разнообразие методов синтаксического анализа (парсинга) XML. Парсер Expat SAX Джеймса Кларка, который теперь основан на библиотеке libxml2, больше не является единственным полнофункциональным парсером. Нам уже знакома возможность парсинга посредством DOM в полном согласии со стандартом W3C. Дополнительные возможности предлагает SimpleXML, который мы рассмотрели в части 1 (см. ), и XMLReader, который проще в понимании и быстрее в работе, чем SAX. Все расширения XML теперь основаны на библиотеке libxml2 проекта GNOME. Эта унифицированная библиотека позволяет разным расширениям взаимодействовать друг с другом. В настоящей статье обсуждаются методы парсинга XML в РНР5 с акцентом на объемные или сложные XML-документы. В ней рассказывается о методах парсинга и о критериях выбора, когда он есть, оптимального метода для синтаксического анализа XML-документов разного типа.

SimpleXML

В первой статье этой серии содержится важная информация об XML и инструкции по началу работы с интерфейсами прикладных программ (API). В ней демонстрировалось, что SimpleXML в сочетании с Document Object Model (DOM) служит идеальным инструментом для разработчиков, имеющих дело с простыми, предсказуемыми и относительно компактными XML-документами.

XML и PHP5

Язык Extensible Markup Language (XML) можно назвать и языком разметки, и форматом хранения текстовых данных; он предоставляет текстовые средства для описания древовидных структур и их применения к информации.

В РНР5 имеются как новые, так и переписанные расширения для XML-парсинга. SimpleXML, DOM и процессор XSLT загружают в память весь XML-документ целиком. Simple API for XML (SAX) и XMLReader относятся к тем парсерам, которые обрабатывают XML-документ по частям. SAX функционирует так же, как в РНР4, но теперь он основан на библиотеке libxml2, а не expat. Тем, кто знаком с DOM по другим языкам, в РНР5 будет легче с ним работать, чем в предыдущих версиях РНР.

Основы XML-парсинга

Существует два основных способа XML-парсинга: на базе деревьев и на базе потоков. Метод дерева предусматривает загрузку в память всего XML-документа целиком. Древовидная структура файла позволяет произвольно обращаться к элементам документа и редактировать XML. Примерами парсеров по методу дерева служат DOM и SimpleXML. Они хранят древовидную структуру в памяти в разных, но взаимодействующих форматах. При поточном парсинге весь документ в память не загружается. В данном случае термин «поток» употребляется в том же смысле, что и при описании поточного аудио. Происходит то же самое и по тем же причинам: данные поступают мелкими порциями с целью экономии полосы пропускания и ресурсов памяти. При поточном парсинге доступен только тот узел, который анализируется в данный момент, а редактирование XML-документа целиком невозможно. Примерами поточных парсеров служат XMLReader и SAX.

Парсеры, работающие по методу дерева

Парсеры, работающие по методу дерева, загружают в память весь документ, так что корень напоминает ствол дерева, а все дочерние, внучатые и более отдаленные потомки и атрибуты служат ветвями. Самый известый парсер, работающий по методу дерева, это DOM. Самый простой — SimpleXML. Рассмотрим тот и другой.

Парсинг при помощи DOM

Стандарт DOM, согласно W3C, представляет собой «...не зависящий от платформы и языка программирования интерфейс, который позволяет программам и сценариям динамически обращаться к документам и редактировать их содержание, структуру и стиль». Библиотека libxml2 проекта GNOME реализует DOM вместе со всеми его методами на языке С. Так как все XML-расширения РНР5 основаны на libxml2, они поддерживают полное взаимодействие друг с другом. Это взаимодействие значительно улучшает их функциональность. Например, можно извлечь элемент при помощи поточного парсера XMLReader, импортировать его в DOM и извлечь данные с использованием XPath. Подтверждение подобной гибкости продемонстрировано .

Парсер DOM работает по методу дерева. Он прост для понимания и применения, так как его структура в памяти напоминает оригинальный XML-документ. DOM передает информацию приложению, создавая дерево объектов, в точности повторяющее дерево элементов из XML-файла, так что каждый элемент XML служит узлом этого дерева. DOM – это стандарт W3C, что принесло ему признание разработчиков ввиду его согласованности с другими языками программирования. Так как DOM строит дерево всего документа, он потребляет большой объем памяти и много ресурсов процессора.

DOM в действии

Если ввиду какого-то ограничения вы вынуждены выбрать единственный парсер, имеет смысл выбрать DOM хотя бы в силу его гибкости. DOM позволяет составлять XML-документы, модифицировать их, обращаться к ним, проверять и преобразовывать их. При этом можно использовать все методы и свойства DOM.Большинство методов DOM второго уровня реализованы с надлежащей поддержкой свойств. Благодаря чрезвычайной гибкости DOM анализируемые документы могут быть чрезвычайно сложными. Однако помните, что за гибкость приходится платить тем, что весь документ загружается в память целиком.

В примере, приведенном в листинге 1, DOM применяется для парсинга документа и извлечения элемента при помощи функции getElementById . Перед ссылкой на идентификатор документ необходимо проверить, установив validateOnParse=true . Согласно стандарту DOM, для этого требуется DTD, который определяет атрибут ID как тип ID.

Листинг 1. Использование DOM с простым документом
validateOnParse = true; $doc->Load("basic.xml"); echo "The element whose id is myelement is: " . $doc->getElementById("myelement")->tagName . "\n"; ?>

Функция getElementsByTagName() возвращает новый экземпляр класса DOMNodeList , содержащий элементы с заданным именем тега. Конечно, нужно пролистать список. Изменение структуры документа во время работы со списком NodeList , выданным функцией getElementsByTagName() , влияет на список NodeList , с которым вы работаете (см. листинг 2). Проверка в данном случае не требуется.

Листинг 2. Метод DOM getElementsByTagName
DOMDocument { DOMNodeList getElementsByTagName(string name); }

В примере из листинга 3 DOM используется с XPath.

Листинг 3. Использование DOM и парсинг с применением XPath
preserveWhiteSpace = false; $doc->Load("book.xml"); $xpath = new DOMXPath($doc); // Мы начали с корневого элемента $query = "//book/chapter/para/informaltable/tgroup/tbody/row/entry[. = "en"]"; $entries = $xpath->query($query); foreach ($entries as $entry) { echo "Found {$entry->previousSibling->previousSibling->nodeValue}," . " by {$entry->previousSibling->nodeValue}\n"; } ?>

Высказав все эти приятные вещи по поводу DOM, я хочу привести пример того, что не надо делать с DOM, а затем, в следующем примере, показать, как это обойти. Листинг 4 иллюстрирует загрузку объемного файла в DOM только с целью извлечения данных из одного атрибута при помощи DomXpath.

Листинг 4. Неправильное использование DOM с XPath при работе с объемным XML-документом
load("tooBig.xml"); $xp = new DomXPath($dom); $result = $xp->query("/blog/entries/entry[@ID = 5225]/title") ; print $result->item(0)->nodeValue ."\n"; ?>

В последнем примере (листинг 5) DOM с XPath применяется точно так же, только данные передаются в XMLReader по одному элементу за раз с использованием метода expand() . При этом узел, переданный XMLReader , преобразуется в DOMElement .

Листинг 5. Правильное использование DOM с XPath при работе с объемным XML-документом
open("tooBig.xml"); while ($reader->read()) { switch ($reader->nodeType) { case (XMLREADER::ELEMENT): if ($reader->localName == "entry") { if ($reader->getAttribute("ID") == 5225) { $node = $reader->expand(); $dom = new DomDocument(); $n = $dom->importNode($node,true); $dom->appendChild($n); $xp = new DomXpath($dom); $res = $xp->query("/entry/title"); echo $res->item(0)->nodeValue; } } } } ?>

Парсинг при помощи SimpleXML

Расширение SimpleXML – еще один способ парсинга XML-документа. Для расширения SimpleXML требуется PHP5 и используется встроенная поддержка XPath. SimpleXML лучше всего работает с несложными данными XML. В том случае, если XML-документ не слишком сложен, глубок и не имеет смешанного контента, SimpleXML проще в применении, чем DOM, как и предполагает его название. Он интуитивно понятен, если вы работаете с известной структурой документа.

SimpleXML в действии

SimpleXML обладает многими преимуществами DOM и проще в программировании. Он позволяет легко обращаться к дереву XML, имеет встроенную поддержку проверки и XPath, а также взаимодействует с DOM, обеспечивая ему поддержку при чтении и записи XML-документов. Документы, анализируемые SimpleXML, пишутся легко и быстро. Однако помните, что, как и в случае DOM, простота и гибкость SimpleXML достигается ценой загрузки в память всего XML-документа целиком.

Код, приведенный в листинге 6, извлекает из примера XML-документа сюжет произведения, содержащийся в элементе

Листинг 6. Извлечение фрагмента текста
Great American Novel Cliff meets Lovely Woman. Loyal Dog sleeps, but wakes up to bark at mailman. 4 9 XML; ?> book->plot; // "Cliff meets Lovely Woman. ..." ?>

С другой стороны, может понадобиться извлечь многострочный адрес. Когда у одного родительского элемента имеется несколько экземпляров дочернего элемента, применяется обычная методика итерирования. Эта функциональность демонстрируется в листинге 7.

Листинг 7. Извлечение нескольких экземпляров элемента
Great American Novel Cliff meets Lovely Woman. 4 9 Man Bites Dog 22 3 XML; ?> book as $book) { echo $book->plot, "
"; } ?

Кроме чтения имен элементов и их значений, SimpleXML может обращаться к атрибутам элемента. В листинге 8 производится обращение к атрибутам элемента; это делается точно так же, как обращение к элементам массива.

Листинг 8. Демонстрация обращения SimpleXML к атрибутам элемента
Great American Novel Cliff meets Lovely Woman. 4 9 Man Bites Dog Reporter invents a prize-winning story. 22 3 XML; ?> book->success as $success) { switch((string) $success["type"]) { case "bestseller": echo $success, " months on bestseller list
"; break; case "bookclubs": echo $success, " bookclub listings
"; break; } } ?>

В последнем примере (см. листинг 9) SimpleXML и DOM используются с расширением XMLReader . При помощи XMLReader данные передаются последовательно, по одному элементу, с использованием метода expand() . Этим методом узел, переданный XMLReader , можно преобразовать в DOMElement , а затем передать SimpleXML.

Листинг 9. Использование SimpleXML и DOM с расширением XMLReader для анализа объемного XML-документа
open("tooBig.xml"); while ($reader->read()) { switch ($reader->nodeType) { case (XMLREADER::ELEMENT): if ($reader->localName == "entry") { if ($reader->getAttribute("ID") == 5225) { $node = $reader->expand(); $dom = new DomDocument(); $n = $dom->importNode($node,true); $dom->appendChild($n); $sxe = simplexml_import_dom($n); echo $sxe->title; } } } } ?>

Потоковые парсеры

Потоковые парсеры называются так потому, что они анализируют XML в потоке, во многом напоминая работу потокового аудио. В каждый момент времени они работают с одним отдельным узлом, а закончив, совершенно забывают о его существовании. XMLReader — это pull-парсер, и программирование для него во многом напоминает извлечение результата запроса к таблице базы данных при помощи курсора. Это облегчает работу с незнакомыми или непредсказуемыми XML-файлами.

Парсинг при помощи XMLReader

XMLReader — это потоковый парсер того типа, который часто называют курсорным или pull-парсером. XMLReader вытягивает информацию из XML-документа по требованию. Он основан на API, полученном из C# XmlTextReader. В PHP 5.1 он включен и задействован по умолчанию и основан на библиотеке libxml2. До выхода PHP 5.1 расширение XMLReader не было включено по умолчанию, но было доступно в PECL (см. ). XMLReader поддерживает пространства имен и проверку, включая DTD и Relaxed NG.

XMLReader в действии

Как потоковый парсер, XMLReader хорошо подходит для работы с объемными XML-документами; программировать в нем намного легче и обычно быстрее, чем в SAX. Это лучший потоковый парсер.

В следующем примере (листинг 10) объемный XML-документ анализируется при помощи XMLReader.

Листинг 10. XMLReader с объемным XML-файлом
open("tooBig.xml"); while ($reader->read()) { switch ($reader->nodeType) { case (XMLREADER::ELEMENT): if ($reader->localName == "entry") { if ($reader->getAttribute("ID") == 5225) { while ($reader->read()) { if ($reader->nodeType == XMLREADER::ELEMENT) { if ($reader->localName == "title") { $reader->read(); echo $reader->value; break; } if ($reader->localName == "entry") { break; } } } } } } } ?>

Парсинг при помощи SAX

Simple API for XML (SAX) представляет собой потоковый парсер. События связаны с читаемым XML-документом, поэтому SAX программируется в стиле обратных вызовов. Существуют события для открывающих и закрывающих тегов элемента, сущностей и ошибок парсинга. Главная причина использования парсера SAX вместо XMLReader заключается в том, что парсер SAX иногда более эффективен и обычно лучше знаком. Важный недостаток — код для парсера SAX получается сложнее, и его труднее писать, чем для XMLReader.

SAX в действии

SAX должен быть знаком тем, кто работал с XML в PHP4, а расширение SAX в PHP5 совместимо с версией, к которой они привыкли. Так как это потоковый парсер, он хорошо справляется с объемными файлами, но это не лучший выбор, чем XMLReader.

В листинге 11 приведен пример обработки объемного XML-документа парсером SAX.

Листинг 11. Использование SAX для анализа объемного XML-файла
hit = true; } else { $this->hit = false; } } if ($this->hit && $elementname == "title") { $this->titleHit = true; } else { $this->titleHit =false; } } //обратный вызов для конца каждого элемента function endElement($parser_object, $elementname) { } //обратный вызов для содержимого каждого элемента function contentHandler($parser_object,$data) { if ($this->titleHit) { echo trim($data)."
"; } } } //Функция запуска парсинга, когда все значения установлены //и файл открыт function doParse($parser_object) { if (!($fp = fopen("tooBig.xml", "r"))); //прокрутка данных while ($data = fread($fp, 4096)) { //анализ фрагмента xml_parse($parser_object, $data, feof($fp)); } } $SaxObject = new SaxClass(); $parser_object = xml_parser_create(); xml_set_object ($parser_object, $SaxObject); //Не меняйте регистр данных xml_parser_set_option($parser_object, XML_OPTION_CASE_FOLDING, false); xml_set_element_handler($parser_object,"startElement","endElement"); xml_set_character_data_handler($parser_object, "contentHandler"); doParse($parser_object); ?>

Заключение

PHP5 предлагает большое разнообразие методов парсинга. Парсинг при помощи DOM, который теперь полностью совместим со стандартом W3C, — знакомый вариант, подходящий для сложных, но относительно компактных документов. SimpleXML — это способ работы с простыми и не слишком объемными документами, а потоковый парсер XMLReader, который легче и быстрее, чем SAX, предпочтителен для очень больших документов.

Loading...Loading...