Статьи

Разбор XML с SimpleXML

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

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

Основное использование

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

 <?xml version="1.0" encoding="utf-8"?>
<languages>
 <lang name="C">
  <appeared>1972</appeared>
  <creator>Dennis Ritchie</creator>
 </lang>
 <lang name="PHP">
  <appeared>1995</appeared>
  <creator>Rasmus Lerdorf</creator>
 </lang>
 <lang name="Java">
  <appeared>1995</appeared>
  <creator>James Gosling</creator>
 </lang>
</languages>

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

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

 <?php
$languages = simplexml_load_file("languages.xml");

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

  SimpleXMLElement Object
 (
     [lang] => Массив
         (
             [0] => SimpleXMLElement Object
                 (
                     [@attributes] => Массив
                         (
                             [name] => C
                         )
                     [появилось] => 1972
                     [создатель] => Деннис Ритчи
                 )
             [1] => SimpleXMLElement Object
                 (
                     [@attributes] => Массив
                         (
                             [name] => PHP
                         )
                     [появилось] => 1995
                     [создатель] => Расмус Лердорф
                 )
             [2] => SimpleXMLElement Object
                 (
                     [@attributes] => Массив
                         (
                             [name] => Java
                         )
                     [появилось] => 1995
                     [создатель] => Джеймс Гослинг
                 )
         )
 ) 

XML содержал элемент корневого languagelangSimpleXMLElementlangSimpleXMLElements Каждый элемент массива соответствует элементу lang

Вы можете получить доступ к свойствам объекта обычным способом с помощью оператора -> Например, $languages->lang[0]SimpleXMLElementlang Этот объект имеет два общедоступных свойства: appearedcreator

 <?php
$languages->lang[0]->appeared;
$languages->lang[0]->creator;

Итерирование по списку языков и отображение их деталей может быть очень легко выполнено с помощью стандартных методов циклов, таких как foreach

 <?php
foreach ($languages->lang as $lang) {
    printf(
        "<p>%s appeared in %d and was created by %s.</p>",
        $lang["name"],
        $lang->appeared,
        $lang->creator
    );
}

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

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

Много раз вы сталкивались с элементами пространства имен при работе с XML из разных веб-сервисов. Давайте изменим наш пример languages.xml

 <?xml version="1.0" encoding="utf-8"?>
<languages
 xmlns:dc="http://purl.org/dc/elements/1.1/">
 <lang name="C">
  <appeared>1972</appeared>
  <dc:creator>Dennis Ritchie</dc:creator>
 </lang>
 <lang name="PHP">
  <appeared>1995</appeared>
  <dc:creator>Rasmus Lerdorf</dc:creator>
 </lang>
 <lang name="Java">
  <appeared>1995</appeared>
  <dc:creator>James Gosling</dc:creator>
 </lang>
</languages>

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

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

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

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

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

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

echo $dc->creator;

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

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

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

foreach($languages->lang as $lang) {
    $dc = $lang->children($ns["dc"]);
    printf(
        "<p>%s appeared in %d and was created by %s.</p>",
        $lang["name"],
        $lang->appeared,
        $dc->creator
    );
}

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

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

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

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

  • URL видео
  • Thumbnail
  • заглавие

Мы начнем с извлечения и загрузки XML:

 <?php
$channel = "channelName";
$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, то увидите, что есть несколько элементов entity Но нас интересуют только миниатюра изображения, видео URL и заголовок. Три элемента являются дочерними элементами groupentry

 <entry><media:group><media:player url="video url"/>
      <media:thumbnail url="video url" height="height" width="width"/>
      <media:title type="plain">Title…</media:title></media:group></entry>

Мы просто перебираем все элементы entry Обратите внимание, что playerthumbnailtitlemedia Итак, нам нужно действовать как в предыдущем примере. Мы получаем пространства имен из документа и используем пространство имен при доступе к элементам.

 <?php
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('<p><a href="%s"><img src="%s" alt="%s"></a></p>',
	        $player, $image, $title);
}

Вывод

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

И если вам понравилось читать этот пост, вы полюбите Learnable ; место, чтобы узнать новые навыки и приемы у мастеров. Участники получают мгновенный доступ ко всем электронным книгам SitePoint и интерактивным онлайн-курсам, таким как Jump Start PHP .

Комментарии к этой статье закрыты. Есть вопрос по PHP? Почему бы не спросить об этом на наших форумах ?