Главная » Полезные статьи » Язык PHP » Как сделать xml parser на PHP
Распечатать статью

Как сделать xml parser на PHP

Я видел много xml parser`ов, но не затрагивал при этом веб-программирование. Теперь же я хочу выяснить и научиться вместе с вами, как сделать простой xml parser в php.

А зачем? Надо!

Не, ну на самом деле: xml-файлы — очень полезная штука. И любой профессионал должен… нет, не должен, а обязан знать, как с ними работать. Мы же хотим стать профессионалами? Если Вы на моем блоге, то такое желание у Вас есть.

Итак…

Мы предполагаем, что знаем, что такое XML и описывать его здесь не будем. Ну, если не знаем, то легко узнаем здесь: http://ru.wikipedia.org/wiki/XML

При поиске способов парсинга XML на PHP, я обнаружил простой набор функций в PHP для работы с XML-файлами, который называется «XML Parser Functions». Парсинг начинается с инициализации парсера вызовом функции xml_parser_create:

$xml_parser = xml_parser_create();

Потом нам нужно сказать парсеру, какие функции будут обрабатывать попадающиеся ему xml-теги и текстовую информацию в процессе парсинга. Т.е. нужно установить некие обработчики:

xml_set_element_handler($xml_parser, “startElement”, “endElement”);

Эта функция отвечает за установку обработчиков начала элемента и конца элемента. Например, если в тексте xml-файла встретится комбинация , то функция startElement сработает, когда парсер найдет элемент , а функция endElement — при нахождении .

Сами же функции startElement и endElement принимают несколько параметров согласно документации по php:

<? function startElement($parser, $name, $attrs) { // $parser - уникальный идентификатор парсера // (т.к. мы можем использовать несколько парсеров) // $name - имя обнаруженного элемента // $attrs - массив атрибутов обнаруженного элемента } function endElement($parser, $name) { // $parser - уникальный идентификатор парсера // $name - имя обнаруженного элемента } ?>

А как же считывать данные из файла? Мы же пока не видели ни одного параметра для этого ни в одной из функций! А об этом дальше: считывание файла возлагается на плечи программиста, т.е. мы должны использовать стандартные функции для работы с файлами:

<? if (!($fp = fopen($file, "r"))) { die("could not open XML input"); } ?>

Открыли файл. А теперь нужно построчно считывать его и скармливать считываемые строки функции xml_parse:

<? while ($data = fgets($fp)) { if (!xml_parse($xml_parser, $data, feof($fp))) { echo "<br>XML Error: ".xml_error_string(xml_get_error_code($xml_parser)); echo " at line ".xml_get_current_line_number($xml_parser); break; } } ?>

Здесь заметим две очень важные вещи. Первая — это то, что функции xml_parse в третьем параметре нужно передать флаг считывания последней строки (true — если строка последняя, false — если нет). Второе — это то, что как и в любом деле, мы должны следить здесь за ошибками. За это отвечают функции xml_get_error_code и xml_error_string. Первая функция получает код ошибки, а вторая — по полученному коду возвращает текстовое описание ошибки. Что в результате возникновения ошибки получится — рассмотрим позже. Не менее полезная функция xml_get_current_line_number скажет нам номер текущей обрабатываемой строки в файле.

И как всегда мы должны освободить занимаемые системой ресурсы. Для парсинга XML — это функция xml_parser_free:

xml_parser_free($xml_parser);

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

<?xml version=»1.0″ encoding=»UTF-8″?>
<root>
<info who=»моя»>
<address ulica=»моя улица!!» kvartira=»12″ dom=»15″>123</address>
<phone>+71234567890</phone>
</info>
</root>

Назовем этот файл data.xml и попытаемся его распарсить с помощью следующего кода:

<? function startElement($parser, $name, $attrs) { global $depth; echo str_repeat("&nbsp;", $depth * 3); // отступы echo "<b>Element: $name</b><br>"; // имя элемента $depth++; // увеличиваем глубину, чтобы браузер показал отступы foreach ($attrs as $attr => $value) { echo str_repeat("&nbsp;", $depth * 3); // отступы // выводим имя атрибута и его значение echo 'Attribute: '.$attr.' = '.$value.'<br>'; } } function endElement($parser, $name) { global $depth; $depth--; // уменьшаем глубину } $depth = 0; $file = "data.xml"; $xml_parser = xml_parser_create(); xml_set_element_handler($xml_parser, "startElement", "endElement"); if (!($fp = fopen($file, "r"))) { die("could not open XML input"); } while ($data = fgets($fp)) { if (!xml_parse($xml_parser, $data, feof($fp))) { echo "<br>XML Error: "; echo xml_error_string(xml_get_error_code($xml_parser)); echo " at line ".xml_get_current_line_number($xml_parser); break; } } xml_parser_free($xml_parser); ?>

В результате разработанного нами простейшего скрипта браузер вывел в свое окно следующую информацию:

Element: ROOT
Element: INFO
Attribute: WHO = моя
Element: ADDRESS
Attribute: ULICA = моя улица!!
Attribute: KVARTIRA = 12
Attribute: DOM = 15
Element: PHONE

Попробуем испортить XML-файл, заменив тег <phone> на <telephone>, а закрывающий тег оставив прежним:

Element: ROOT
Element: INFO
Attribute: WHO = моя
Element: ADDRESS
Attribute: ULICA = моя улица!!
Attribute: KVARTIRA = 12
Attribute: DOM = 15
Element: TELEPHONE

XML Error: Mismatched tag at line 5

Ух ты! Сообщения об ошибках работают! Причем довольно информативные.

Эх, я забыл еще одну вещь… Мы же не вывели текст, содержащийся внутри тегов address и phone. Исправляем наш недочет — добавляем текстовый обработчик с помощью функции xml_set_character_data_handler:

xml_set_character_data_handler($xml_parser, ’stringElement’);

И добавляем в код саму функцию-обработчик:

<? function stringElement($parser, $str) { if (strlen(trim($str)) > 0) { global $depth; echo str_repeat("&nbsp;", $depth * 3); // отступ echo 'String: '.$str.'<br>'; // выводим строку } } ?>

Посмотрим теперь на вывод:

Element: ROOT
Element: INFO
Attribute: WHO = моя
Element: ADDRESS
Attribute: ULICA = моя улица!!
Attribute: KVARTIRA = 12
Attribute: DOM = 15
String: 123
Element: PHONE
String: +71234567890

О! Теперь вывели все!

Кстати, кто-нибудь заметил, что имена тегов и атрибутов все большими буквами написаны? Странно… они же в нашем xml-файле малыми буквами обозначены. Видимо где-то какие-то настройки установлены, чтобы делать uppercase…

Ааа, нашел! Оказывается есть еще функция xml_parser_set_option:

xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);

Таким вызовом мы отменяем вывод имен атрибутов и имен тегов большими буквами:

Element: root
Element: info
Attribute: who = моя
Element: address
Attribute: ulica = моя улица!!
Attribute: kvartira = 12
Attribute: dom = 15
String: 123
Element: phone
String: +71234567890

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

Источник: internet-technologies.ru

Вы можете оставить комментарий, или обратную ссылку на Ваш сайт.

Оставить комментарий

Похожие статьи