Перевод данных XML-файла в объекты и классы PHP

Первое, что нужно сделать, если мы хотим работать с XML -данными в PHP при помощи расширения DOM XML, это перевести имеющиеся данные в объекты и классы DOM. Это можно сделать несколькими способами.

1. С помощью функции domxml_open_mem .

Синтаксис:

object domxml_open_mem (string str)

В качестве параметра эта функция принимает строку str, содержащую XML -документ. Результатом ее работы является объект класса, называемого DOMDocument.

2. С помощью функции domxml_open_file .

Синтаксис:

object domxml_open_file (string filename)

Эта функция обрабатывает XML -файл, имя которого задается параметром filename, и переводит его в объект классаDOMDocument. Доступ к файлу производится только на чтение.

Такие функции, как domxml_open_mem() и domxml_open_file() , как правило, нужно вызывать перед вызовом любых других функций, связанных с расширением DOM.

Эти функции преобразуют XML -файл в дерево объектов. К таким объектам можно обращаться с помощью различных методов. В частности, для выделения корневого элемента используется метод DomDocument->document_element() .

Еще существует функция domxml_new_doc(string version) , которая создает новый пустой XML -документ. Ее параметром является номер версии создаваемого документа. Но ее мы касаться не будем, а будем считать, что XML -файл уже создан.

<?

//считываем файл "persons.xml" в строку

$xmlstr = join('',file('persons.xml'));

// переводим строку с xml-файлом

// в дерево объектов. Если операция

// прошла неудачно, то выводим

// ошибку и прекращаем работу.

if(!$dom = domxml_open_mem($xmlstr)) {

echo "Ошибка при разборе документа\n";

exit;

}

// можно посмотреть, как выглядит

// этот объект

print_r($dom);

echo "<hr>";

// выделяем корневой элемент

// дерева объектов.

// В нашем случае это будет

// элемент <collection>

$root = $dom->document_element();

print_r($root);

echo "<hr>";

?>

Пример 14.3. Перевод XML-файла в дерево объектов PHP и выделение корневого элемента

Итак, каждому элементу XML -файла мы поставили в соответствие какой-то объект. Теперь нужно научиться перемещаться по дереву объектов и обращаться с этими объектами: получать и изменять их значения, находить их потомков и предков, удалять объекты.

Обход дерева объектов

Для получения значения текущего узла (вне зависимости от его типа) используют метод DomNode->node_value() или DomNode->get_content() для получения содержимого узла.

Для получения значения атрибута используется метод DomElement->get_attribute (attr_name) . А метод DomNode->child_nodes() возвращает массив потомков данного узла.

Для того чтобы сделать обход дерева объектов, полезно еще уметь различать объекты по типам, т.е. определять, является ли узелэлементом (тегом), текстом, атрибутом и т.п. Для этого используются специальные константы. XML_ELEMENT_NODE определяет, является ли узел элементом, XML_ATTRIBUTE_NODE определяет, является ли узел атрибутом, и XML_TEXT_NODE определяет, является ли узел куском текста. Эти константы имеют целочисленные значения 1, 2 и 3 соответственно. Использование этих констант полезно, поскольку переводы строки, применяемые для удобочитаемости XML -файлов, тоже становятся узлами.

<?

// сначала делаем то же,

// что и в предыдущем примере

$xmlstr = join('',file('persons.xml'));

if(!$dom = domxml_open_mem($xmlstr)) {

echo "Ошибка при разборе документа\n";

exit;

}

$root = $dom->document_element();

// Получаем массив потомков

// родительского узла

// (в нашем случае это массив <person>)

$nodes = $root->child_nodes();

print_r($nodes);

echo "<hr>";

// Начинаем обработку каждого

// узла в массиве

foreach($nodes as $node){

// Если текущий узел – один

// из узлов <person>, то

// продолжаем ее обработку,

// чтобы получить информацию

// об этой личности

if ($node->tagname=='person'){

// Создаем массив, куда

// будем собирать информацию

// о рассматриваемой личности

$currentPers = array();

// Получаем id личности,

// который хранится в атрибуте 'id'

$currentPers['id'] =

$node->get_attribute('id');

// Получаем массив потомков

// <person>. Это вся

// информация о личности

// (<name>,<birth> и т.д.)

$persons_info =

$node->child_nodes();

// Перебираем все дочерние

// узлы $node

foreach ($persons_info as $info){

// проверяем, является ли узел

// элементом (xml-тегом)

if ($info->type==

XML_ELEMENT_NODE) {

// тогда метод tagname

// возвратит имя этого

// элемента (тега), а метод

// get_content() –

// его содержимое

$currentPers[$info->tagname] =

$info->get_content();

}

}

// выводим на экран полученные

// массивы

print_r ($currentPers);

 

echo "<br>";

}

}

?>

Пример 14.4. Обход дерева XML

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

...

<person id="20">

<name>

<first>Иван</first>

<last>Иванов</last>

</name>

...

Тогда в наш предыдущий пример вставим (после вывода на экран полученных массивов) строчку для поиска электронного адреса Ивана Иванова.

...

$str = $currentPers["email"];

if ($currentPers["name"] ==

"Иван Иванов" )

echo "Здравствуйте, Иван! " .

"Ваш e-mail $str";

...