Основы работы с модулем SimpleXML

Для работы части примеров руководства к модулю SimpleXML потребуется XML-строка. Вместо повторения строки в каждом примере, определим строку в файле и подключим файл в примерах. При тестировании методов модуля подключите этот файл или создайте отдельный XML-документ и считайте строку в формате XML функцией simplexml_load_file().

Пример #1 Файл examples/simplexml-data.php с XML-строкой для включения

<?php

$xmlstr
= <<<XML
<?xml version='1.0' standalone='yes'?>
<movies>
<movie>
<title>PHP: Устройство парсера</title>
<characters>
<character>
<name>Ms. Coder</name>
<actor>Onlivia Actora</actor>
</character>
<character>
<name>Mr. Coder</name>
<actor>El Act&#211;r</actor>
</character>
</characters>
<plot>
Так что же, PHP — язык программирования или всё же скриптовый язык?
Истина откроется в этом захватывающем пародийном фильме ужасов
в формате документальной драмы.
</plot>
<great-lines>
<line>Каких только веб-задач не решает PHP!</line>
</great-lines>
<rating type="thumbs">7</rating>
<rating type="stars">5</rating>
</movie>
</movies>
XML;

?>

Простота работы с модулем SimpleXML проявляется при извлечении строки или числа из базового XML-документа.

Пример #2 Чтение сюжета из элемента <plot>

<?php

include 'examples/simplexml-data.php';

$movies = new SimpleXMLElement($xmlstr);

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

?>

Результат выполнения приведённого примера:


   Так что же, PHP — язык программирования или всё же скриптовый язык?
   Истина откроется в этом захватывающем пародийном фильме ужасов
   в формате документальной драмы.

Для доступа к элементам XML-документа, названия которых содержат недопустимые, с точки зрения PHP-соглашения об именовании, символы наподобие дефиса, название элемента заключают в фигурные скобки и апострофы.

Пример #3 Доступ к строке элемента <line>

<?php

include 'examples/simplexml-data.php';

$movies = new SimpleXMLElement($xmlstr);

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

?>

Результат выполнения приведённого примера:

Каких только веб-задач не решает PHP!

Пример #4 Доступ к неуникальным элементам средствами модуля SimpleXML

Для перебора множественных одноимённых дочерних элементов узла применяют стандартные методы итерации.

<?php

include 'examples/simplexml-data.php';

$movies = new SimpleXMLElement($xmlstr);

/* Выведем значение элемента <name> каждого узла <character> */
foreach ($movies->movie->characters->character as $character) {
echo
$character->name, ' играет ', $character->actor, PHP_EOL;
}

?>

Результат выполнения приведённого примера:

Ms. Coder играет Onlivia Actora
Mr. Coder играет El ActÓr

Замечание:

Свойства наподобие $movies->movie, которое содержал предыдущий пример, — не массивы, а итерируемые и доступные как массив объекты.

Пример #5 Работа с атрибутами

До сих пор мы получали только названия и значения элементов. Модуль SimpleXML умеет получать доступ и к атрибутам элементов. Доступ к атрибутам элемента получают аналогично доступу к элементам массива.

<?php

include 'examples/simplexml-data.php';

$movies = new SimpleXMLElement($xmlstr);

/* Доступ к узлам <rating> первого фильма
* и вывод шкалы оценок */
foreach ($movies->movie[0]->rating as $rating) {
switch ((string)
$rating['type']) { // Получаем атрибуты элемента по индексу
case 'thumbs':
echo
$rating, ' thumbs up';
break;
case
'stars':
echo
$rating, ' stars';
break;
}
}

?>

Результат выполнения приведённого примера:

7 thumbs up5 stars

Пример #6 Сравнение элементов и атрибутов с текстом

Для сравнения со строкой или передачи в функцию, которая требует строку, элементы или атрибуты приводят к строке оператором приведения (string), иначе PHP обрабатывает элементы и атрибуты как объекты.

<?php

include 'examples/simplexml-data.php';

$movies = new SimpleXMLElement($xmlstr);

if ((string)
$movies->movie->title == 'PHP: Устройство парсера') {
print
'Мой любимый фильм: ';
}

echo
"«", htmlentities((string) $movies->movie->title), "»";

?>

Результат выполнения приведённого примера:

Мой любимый фильм: «PHP: Устройство парсера»

Пример #7 Сравнение двух элементов

Два объекта SimpleXMLElement считаются разными, даже если указывают на один и тот же элемент.

<?php

include 'examples/simplexml-data.php';

$movies1 = new SimpleXMLElement($xmlstr);
$movies2 = new SimpleXMLElement($xmlstr);
var_dump($movies1 == $movies2); // false

?>

Результат выполнения приведённого примера:

bool(false)

Пример #8 XPath — язык запросов к элементам XML-документа

Модуль SimpleXML включает встроенную поддержку языка XPath. Поиск всех элементов <character>.

Запись '//' работает как подстановочный знак, или шаблон. Один слеш опускают, чтобы указать абсолютный путь:

<?php

include 'examples/simplexml-data.php';

$movies = new SimpleXMLElement($xmlstr);

foreach (
$movies->xpath('//character') as $character) {
echo
$character->name, ' играет ', $character->actor, PHP_EOL;
}

?>

Результат выполнения приведённого примера:

Ms. Coder играет Onlivia Actora
Mr. Coder играет by El ActÓr

Пример #9 Установка значений

Каждый элемент в объекте модуля SimpleXML доступен для изменения.

<?php

include 'examples/simplexml-data.php';

$movies = new SimpleXMLElement($xmlstr);

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

echo
$movies->asXML();

?>

Результат выполнения приведённого примера:

<?xml version="1.0" standalone="yes"?>
<movies>
 <movie>
  <title>PHP: Устройство парсера</title>
  <characters>
   <character>
    <name>Miss Coder</name>
    <actor>Onlivia Actora</actor>
   </character>
   <character>
    <name>Mr. Coder</name>
    <actor>El Act&#xD3;r</actor>
   </character>
  </characters>
  <plot>
   Так что же, PHP — язык программирования или всё же скриптовый язык?
   Истина откроется в этом захватывающем пародийном фильме ужасов
   в формате документальной драмы.
  </plot>
  <great-lines>
   <line>Каких только веб-задач не решает PHP!</line>
  </great-lines>
  <rating type="thumbs">7</rating>
  <rating type="stars">5</rating>
 </movie>
</movies>

Пример #10 Добавление элементов и атрибутов

Модуль SimpleXML легко добавляет дочерние элементы и атрибуты.

<?php

include 'examples/simplexml-data.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();

?>

Результат выполнения приведённого примера:

<?xml version="1.0" standalone="yes"?>
<movies>
 <movie>
  <title>PHP: Устройство парсера</title>
  <characters>
   <character>
    <name>Ms. Coder</name>
    <actor>Onlivia Actora</actor>
   </character>
   <character>
    <name>Mr. Coder</name>
    <actor>El Act&#xD3;r</actor>
   </character>
  <character><name>Mr. Parser</name><actor>John Doe</actor></character></characters>
  <plot>
   Так что же, PHP — язык программирования или всё же скриптовый язык?
   Истина откроется в этом захватывающем пародийном фильме ужасов
   в формате документальной драмы.
  </plot>
  <great-lines>
   <line>Каких только веб-задач не решает PHP!</line>
  </great-lines>
  <rating type="thumbs">7</rating>
  <rating type="stars">5</rating>
 <rating type="mpaa">PG</rating></movie>
</movies>

Пример #11 Взаимодействие с модулем DOM

В PHP предусмотрели механизм преобразования XML-узлов между форматами модулей SimpleXML и DOM. Пример показывает, как изменить DOM-элемент в SimpleXML.

<?php

$dom
= new DOMDocument();
$dom->loadXML('<books><book><title>чепуха</title></book></books>');
if (!
$dom) {
echo
'Ошибка при разборе документа';
exit;
}

$books = simplexml_import_dom($dom);

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

?>

Результат выполнения приведённого примера:

чепуха

Пример #12 Работа с пространствами имён

<?php

$data
= <<<XML
<movies xmlns="http://default" xmlns:a="http://a">
<movie xml:id="movie1" a:link="IMDB">
<a:actor>Onlivia Actora</a:actor>
</movie>
</movies>
XML;

$movies = simplexml_load_string($data);

// Пространство имён http://www.w3.org/XML/1998/namespace доступно по префиксу "xml"
echo $movies->movie->attributes("xml", true)["id"] . "\n";

// Атрибуты в пространстве имён доступны через метод attributes()
echo $movies->movie->attributes("a", true)["link"] . "\n";

// Доступ к атрибутам пространства имён возможен по URI-идентификатору, а не только по префиксу
echo $movies->movie->attributes("http://a")["link"] . "\n";

// Дочерние элементы доступны через метод children()
echo $movies->movie->children("http://a")->actor . "\n";

// Вызов метода xpath() с префиксом требует предварительной регистрации этого префикса
$movies->registerXPathNamespace("a", "http://a");
echo
count($movies->xpath("//a:actor")) . "\n";

// Даже пространство имён по умолчанию потребуется зарегистрировать
$movies->registerXPathNamespace("default", "http://default");
echo
count($movies->xpath("//default:movie")) . "\n";

// Запрос возвращает пустой результат,
// поскольку элемент movie принадлежит пространству имён, которое не указали в запросе
echo count($movies->xpath("//movie")) . "\n";

?>