Парсеры xml файла на php. Для чего нужны XML-парсеры и чем они могут быть полезны

Many examples in this reference require an XML string. Instead of repeating this string in every example, we put it into a file which we include in each example. This included file is shown in the following example section. Alternatively, you could create an XML document and read it with simplexml_load_file() .

Example #1 Include file example.php with XML string

$xmlstr = <<


PHP: Behind the Parser


Ms. Coder
Onlivia Actora


Mr. Coder
El ActÓr


So, this language. It"s like, a programming language. Or is it a
scripting language? All is revealed in this thrilling horror spoof
of a documentary.




7
5


XML;
?>

The simplicity of SimpleXML appears most clearly when one extracts a string or number from a basic XML document.

Example #2 Getting

include "example.php" ;

echo $movies -> movie [ 0 ]-> plot ;
?>

So, this language. It"s like, a programming language. Or is it a scripting language? All is revealed in this thrilling horror spoof of a documentary.

Accessing elements within an XML document that contain characters not permitted under PHP"s naming convention (e.g. the hyphen) can be accomplished by encapsulating the element name within braces and the apostrophe.

Example #3 Getting

include "example.php" ;

echo $movies -> movie ->{ "great-lines" }-> line ;
?>

The above example will output:

PHP solves all my web problems

Example #4 Accessing non-unique elements in SimpleXML

When multiple instances of an element exist as children of a single parent element, normal iteration techniques apply.

include "example.php" ;

$movies = new SimpleXMLElement ($xmlstr );

/* For each node, we echo a separate . */
foreach ($movies -> movie -> characters -> character as $character ) {
echo $character -> name , " played by " , $character -> actor , PHP_EOL ;
}

?>

The above example will output:

Properties ($movies->movie in previous example) are not arrays. They are iterable and accessible objects.

Example #5 Using attributes

So far, we have only covered the work of reading element names and their values. SimpleXML can also access element attributes. Access attributes of an element just as you would elements of an array .

include "example.php" ;

$movies = new SimpleXMLElement ($xmlstr );

/* Access the nodes of the first movie.
* Output the rating scale, too. */
foreach ($movies -> movie [ 0 ]-> rating as $rating ) {
switch((string) $rating [ "type" ]) { // Get attributes as element indices
case "thumbs" :
echo $rating , " thumbs up" ;
break;
case "stars" :
echo $rating , " stars" ;
break;
}
}
?>

The above example will output:

7 thumbs up5 stars

Example #6 Comparing Elements and Attributes with Text

To compare an element or attribute with a string or pass it into a function that requires a string, you must cast it to a string using (string) . Otherwise, PHP treats the element as an object.

include "example.php" ;

$movies = new SimpleXMLElement ($xmlstr );

if ((string) $movies -> movie -> title == "PHP: Behind the Parser" ) {
print "My favorite movie." ;
}

echo htmlentities ((string) $movies -> movie -> title );
?>

The above example will output:

My favorite movie.PHP: Behind the Parser

Example #7 Comparing Two Elements

Two SimpleXMLElements are considered different even if they point to the same element since PHP 5.2.0.

include "example.php" ;

$movies1 = new SimpleXMLElement ($xmlstr );
$movies2 = new SimpleXMLElement ($xmlstr );
var_dump ($movies1 == $movies2 ); // false since PHP 5.2.0
?>

The above example will output:

Example #8 Using XPath

SimpleXML includes built-in XPath support. To find all elements:

include "example.php" ;

$movies = new SimpleXMLElement ($xmlstr );

foreach ($movies -> xpath ("//character" ) as $character ) {
echo $character -> name , " played by " , $character -> actor , PHP_EOL ;
}
?>

"// " serves as a wildcard. To specify absolute paths, omit one of the slashes.

The above example will output:

Ms. Coder played by Onlivia Actora Mr. Coder played by El ActÓr

Example #9 Setting values

Data in SimpleXML doesn"t have to be constant. The object allows for manipulation of all of its elements.

include "example.php" ;
$movies = new SimpleXMLElement ($xmlstr );

$movies -> movie [ 0 ]-> characters -> character [ 0 ]-> name = "Miss Coder" ;

echo $movies -> asXML ();
?>

The above example will output:

PHP: Behind the Parser Miss Coder Onlivia Actora Mr. Coder El ActÓr PHP solves all my web problems 7 5

Example #10 Adding elements and attributes

Since PHP 5.1.3, SimpleXML has had the ability to easily add children and attributes.

include "example.php" ;
$movies = new SimpleXMLElement ($xmlstr );

$character = $movies -> movie [ 0 ]-> characters -> addChild ("character" );
$character -> addChild ("name" , "Mr. Parser" );
$character -> addChild ("actor" , "John Doe" );

$rating = $movies -> movie [ 0 ]-> addChild ("rating" , "PG" );
$rating -> addAttribute ("type" , "mpaa" );

echo $movies -> asXML ();
?>

The above example will output:

PHP: Behind the Parser Ms. Coder Onlivia Actora Mr. Coder El ActÓr Mr. ParserJohn Doe So, this language. It"s like, a programming language. Or is it a scripting language? All is revealed in this thrilling horror spoof of a documentary. PHP solves all my web problems 7 5 PG

Example #11 DOM Interoperability

PHP has a mechanism to convert XML nodes between SimpleXML and DOM formats. This example shows how one might change a DOM element to SimpleXML.

$dom = new DOMDocument ;
$dom -> loadXML ("blah" );
if (! $dom ) {
echo "Error while parsing the document" ;
exit;
}

$books = simplexml_import_dom ($dom );

echo $books -> book [ 0 ]-> title ;
?>

The above example will output:

3 years ago

There is a common "trick" often proposed to convert a SimpleXML object to an array, by running it through json_encode() and then json_decode(). I"d like to explain why this is a bad idea.

Most simply, because the whole point of SimpleXML is to be easier to use and more powerful than a plain array. For instance, you can write bar -> baz [ "bing" ] ?> and it means the same thing as bar [ 0 ]-> baz [ 0 ][ "bing" ] ?> , regardless of how many bar or baz elements there are in the XML; and if you write bar [ 0 ]-> baz [ 0 ] ?> you get all the string content of that node - including CDATA sections - regardless of whether it also has child elements or attributes. You also have access to namespace information, the ability to make simple edits to the XML, and even the ability to "import" into a DOM object, for much more powerful manipulation. All of this is lost by turning the object into an array rather than reading understanding the examples on this page.

Additionally, because it is not designed for this purpose, the conversion to JSON and back will actually lose information in some situations. For instance, any elements or attributes in a namespace will simply be discarded, and any text content will be discarded if an element also has children or attributes. Sometimes, this won"t matter, but if you get in the habit of converting everything to arrays, it"s going to sting you eventually.

Of course, you could write a smarter conversion, which didn"t have these limitations, but at that point, you are getting no value out of SimpleXML at all, and should just use the lower level XML Parser functions, or the XMLReader class, to create your structure. You still won"t have the extra convenience functionality of SimpleXML, but that"s your loss.

8 years ago

If you need to output valid xml in your response, don"t forget to set your header content type to xml in addition to echoing out the result of asXML():

$xml = simplexml_load_file ("..." );
...
... xml stuff
...

//output xml in your response:
header ("Content-Type: text/xml" );
echo $xml -> asXML ();
?>

1 year ago

If your xml string contains booleans encoded with "0" and "1", you will run into problems when you cast the element directly to bool:

$xmlstr = <<

1
0

XML;
$values = new SimpleXMLElement($xmlstr);
$truevalue = (bool)$values->truevalue; // true
$falsevalue = (bool)$values->falsevalue; // also true!!!

Instead you need to cast to string or int first:

$truevalue = (bool)(int)$values->truevalue; // true
$falsevalue = (bool)(int)$values->falsevalue; // false

8 years ago

From the README file:

SimpleXML is meant to be an easy way to access XML data.

SimpleXML objects follow four basic rules:

1) properties denote element iterators
2) numeric indices denote elements
3) non numeric indices denote attributes
4) string conversion allows to access TEXT data

When iterating properties then the extension always iterates over
all nodes with that element name. Thus method children() must be
called to iterate over subnodes. But also doing the following:
foreach ($obj->node_name as $elem) {
// do something with $elem
}
always results in iteration of "node_name" elements. So no further
check is needed to distinguish the number of nodes of that type.

When an elements TEXT data is being accessed through a property
then the result does not include the TEXT data of subelements.

Known issues
============

Due to engine problems it is currently not possible to access
a subelement by index 0: $object->property.

8 years ago

A quick tip on xpath queries and default namespaces. It looks like the XML-system behind SimpleXML has the same workings as I believe the XML-system .NET uses: when one needs to address something in the default namespace, one will have to declare the namespace using registerXPathNamespace and then use its prefix to address the otherwise in the default namespace living element.

$string = <<

Forty What?
Joe
Jane

I know that"s the answer -- but what"s the question?


XML;

$xml = simplexml_load_string ($string );
$xml -> registerXPathNamespace ("def" , "http://www.w3.org/2005/Atom " );

$nodes = $xml -> xpath ("//def:document/def:title" );

?>

8 years ago

Using stuff like: is_object($xml->module->admin) to check if there actually is a node called "admin", doesn"t seem to work as expected, since simplexml always returns an object- in that case an empty one - even if a particular node does not exist.
For me good old empty() function seems to work just fine in such cases.

9 years ago

While SimpleXMLElement claims to be iterable, it does not seem to implement the standard Iterator interface functions like::next and::reset properly. Therefore while foreach() works, functions like next(), current(), or each() don"t seem to work as you would expect -- the pointer never seems to move or keeps getting reset.

5 years ago

Если кодировка XML-документа отличается от UTF-8, объявление кодировки должно следовать сразу после version="..." и перед standalone="...". Это требование стандарта XML.

If encoding XML-document differs from UTF-8. Encoding declaration should follow immediately after the version = "..." and before standalone = "...". This requirement is standard XML.


Ok

Русский язык. Russian language
Fatal error: Uncaught exception "Exception" with message "String could not be parsed as XML" in...

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 parser . Но жалко, что не в пхп. Ну ниче, счас наверстаем

Я видел много 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:



// (т.к. мы можем использовать несколько парсеров)

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

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

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

Здесь заметим две очень важные вещи. Первая – это то, что функции 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-файл с очень простой структурой:




123

71234567890

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

function startElement($parser, $name, $attrs) {
global $depth;echo str_repeat (" ", $depth * 3); // отступы
echo "Element: $name
"; // имя элемента

$depth++; // увеличиваем глубину, чтобы браузер показал отступы

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 "
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-файл, заменив тег На , а закрывающий тег оставив прежним:

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

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

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

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-файлов. Я еще слышал про какие-то другие более мощные методы, но их буду рассматривать, когда сам изучу немного

nika, Вам нужно вставить вызов
xml_set_character_data_handler($xml_parser, ’stringElement’);
после
xml_set_element_handler($xml_parser, “startElement”, “endElement”);

В общем для правильного отображения нужно соблюдать следующее:
1. нужно, чтобы xml-файл был в кодировке UTF-8
2. в xml-файле первая строчка должна быть такой:
< ?xml version="1.0" encoding="UTF-8"?>
3. нужно инициализировать парсер так:
xml_parser_create(”UTF-8?);
4. нужно перед выводом содержимого xml-файла в браузер настроить последний на кодировку UTF-8:
header(“Content-Type: text/html; charset=utf-8?);

Для отображения текста на русском языке используем
iconv(”UTF-8?,”windows-1251?, $attr), где $attr, то что нужно вывести.

Есть такие два класса интересных в стандартной библеотеке PHP5 – DOMDocument() и XSLTProcesor() использовал на довольно крупных проектах – не жалуюсь =)

Вообще у PHP есть еще одна библиотечка для разбора XML по принципу SAX – называется XMLReader.

    Господа, как вывести из xml с помощью simplexml не стандартные теги, например?
    Переменная вида $text = $item->yandex:full-text не работает.

    Все ОК, только обратите внимание на наличие следующего параметра,

    function cdata($parser, $cdata)
    {
    var_dump($parser, $cdata);
    }

    xml_set_character_data_handler($this->parser, “cdata”);

    Без него не хочет парсить XML с CDATA…. размером в 1.5 метра

    2Nika, Функция header() работает только в том случае, если до нее не было ничего выведено, то бишь первым действие производили ее, т.к. мы отсылаем заголовки на эту страницу, которые говорят нам, что текст нужно переводить в кодировку UTF-8. Судя по вашей ошибке у вас есть пропуски строк, поэтому сделайте вот так:

    Значение == порядковый номер строки
    header(”Content-Type: text/html; charset=utf-8?); == 2

    Всё намного проще делается в действительности
    yurban.ru/development/php_xml_parser

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

Используя расширение SimpleXML в PHP, которое было добавлено еще в PHP 5.0, работать с XML очень легко и просто. В этой статье я покажу вам, как это делать.

Основы использования

Давайте начнем со следующего примера languages.xml :


>

> 1972>
> Dennis Ritchie>
>

> 1995>
> Rasmus Lerdorf>
>

> 1995>
> James Gosling>
>
>

Данный XML-документ содержит список языков программирования с некоторой информацией о каждом языке: год его реализации и имя его создателя.

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

Обе функции считывают все дерево DOM в память и возвращают объект SimpleXMLElement . В приведенном выше примере, объект сохраняется в переменной $languages. Вы можете использовать функции var_dump() или print_r() , чтобы получить подробную информацию о возвращенном объект, если хотите.

SimpleXMLElement Object
[ lang] => Array
[ 0 ] => SimpleXMLElement Object
[ @ attributes] => Array
[ name] => C
[ appeared] => 1972
[ creator] => Dennis Ritchie
[ 1 ] => SimpleXMLElement Object
[ @ attributes] => Array
[ name] => PHP
[ appeared] => 1995
[ creator] => Rasmus Lerdorf
[ 2 ] => SimpleXMLElement Object
[ @ attributes] => Array
[ name] => Java
[ appeared] => 1995
[ creator] => James Gosling
)
)

Данный XML содержит корневой элемент languages , внутри которого находятся три элемента lang. Каждый элемент массива соответствует элементу lang в XML-документе.

Вы можете получить доступ к свойствам объекта при помощи оператора -> . Например, $languages->lang вернет вам объект SimpleXMLElement, который соответствует первому элементу lang . Этот объект содержит два свойства: appeared и creator.

$languages -> lang [ 0 ] -> appeared ;
$languages -> lang [ 0 ] -> creator ;

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

foreach ($languages -> lang as $lang ) {
printf (
"" ,
$lang [ "name" ] ,
$lang -> appeared ,
$lang -> creator
) ;
}

Обратите внимание, как я получил доступ к имени атрибута элемента lang, чтобы получить название языка. Таким образом Вы можете получить доступ к любому атрибуту элемента представленого в виде объекта SimpleXMLElement.

Работа с пространствами имен

Во время работы с XML различных веб-сервисов вы не раз столкнетесь с пространствами имен элементов. Давайте изменим наш languages.xml , чтобы показать пример использования пространства имен:



xmlns:dc =>

> 1972>
> Dennis Ritchie>
>

> 1995>
> Rasmus Lerdorf>
>

> 1995>
> James Gosling>
>
>

Теперь элемент creator помещается в пространстве имен dc , который указывает на http://purl.org/dc/elements/1.1/. Если вы попытаетесь распечатать создателей языка, используя наш предыдущий код, то он не будет работать. Для того, чтобы читать пространства имен элементов вам необходимо использовать один из следующих подходов.

Первый подход заключается в использовании имен URI непосредственно в коде, когда обращаемся к пространству имен элементов. В следующем примере показано, как это делается:

$dc = $languages -> lang [ 1 ] - > children("http://purl.org/dc/elements/1.1/" ) ;
echo $dc -> creator ;

Метод children() принимает пространство имен и возвращает дочерние элементы, которые начинаются с префикса. Он принимает два аргумента, первый из которых является пространством имен XML, и второй необязательный аргумент, который по умолчанию равен false . Если второй аргумент установлен как TRUE, пространство имен будет рассмотрено как префикс. Если FALSE, то пространство имен будет рассмотрено как пространство имен URL.

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

$namespaces = $languages -> getNamespaces (true ) ;
$dc = $languages -> lang [ 1 ] -> children ($namespaces [ "dc" ] ) ;

echo $dc -> creator ;

Метод GetNamespaces() возвращает массив имен префиксов и связанные с ними URI. Он принимает дополнительный параметр, который по умолчанию равен false . Если вы установите его как true , то этот метод будет возвращать имена, используемые в родительских и дочерних узлах. В противном случае, он находит пространства имен, используемые только в родительском узле.

Теперь вы можете пройтись по списку языков следующим образом:

$languages = simplexml_load_file ("languages.xml" ) ;
$ns = $languages -> getNamespaces (true ) ;

foreach ($languages -> lang as $lang ) {
$dc = $lang -> children ($ns [ "dc" ] ) ;
printf (
"

%s появился в %d и был создан %s .

" ,
$lang [ "name" ] ,
$lang -> appeared ,
$dc -> creator
) ;
}

Практический пример - Парсинг видео-канала с YouTube

Давайте рассмотрим пример, который получает RSS-feed с канала YouTube и отображает ссылки на все видео из него. Для этого нужно обратится по следующему адресу:

http://gdata.youtube.com/feeds/api/users/xxx/uploads

URL возвращает список последних видео с данного канала в формате XML. Мы распарсим XML и получим следующую информацию для каждого видео:

  • Ссылка на видео
  • Миниатюра
  • Название

Мы начнем с поиска и загрузки XML:

$channel = "Имя_канала" ;
$url = "http://gdata.youtube.com/feeds/api/users/" . $channel . "/uploads" ;
$xml = file_get_contents ($url ) ;

$feed = simplexml_load_string ($xml ) ;
$ns = $feed -> getNameSpaces (true ) ;

Если вы посмотрите на XML-feed, то вы можете увидеть, что там есть несколько элементов entity , каждый из которых хранит подробную информацию о конкретном видео с канала. Но мы используем только миниатюры изображений, адрес видео и название. Эти три элемента являются потомками элемента group , который, в свою очередь, является дочерним для entry :

>

>



Title…>

>

>

Мы просто пройдемся по всем элементам entry , и для каждого из них извлечем необходимую информацию. Обратите внимание, что player, thumbnail и title находятся в пространстве имен media. Таким образом, мы должны действовать, как в предыдущем примере. Мы получаем имена из документа и используем пространство имен при обращении к элементам.

foreach ($feed -> entry as $entry ) {
$group = $entry -> children ($ns [ "media" ] ) ;
$group = $group -> group ;
$thumbnail_attrs = $group -> thumbnail [ 1 ] -> attributes () ;
$image = $thumbnail_attrs [ "url" ] ;
$player = $group -> player -> attributes () ;
$link = $player [ "url" ] ;
$title = $group -> title ;
printf ("

" ,
$player , $image , $title ) ;
}

Заключение

Теперь, когда вы знаете, как использовать SimpleXML для разбора XML-данных, вы можете улучшить свои навыки путем анализа различных XML-каналов с различными API. Но важно учитывать, что SimpleXML считывает весь DOM в память, так что если вы парсите большой набор данных, то вы можете столкнуться с нехваткой памяти. Чтобы узнать больше о SimpleXML прочтите документацию .


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