Php обход дерева 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 -файлов, тоже становятся узлами.

 $root = $dom->document_element(); // Получаем массив потомков // родительского узла // (в нашем случае это массив ) $nodes = $root->child_nodes(); print_r($nodes); echo "
"; // Начинаем обработку каждого // узла в массиве foreach($nodes as $node)< // Если текущий узел – один // из узлов , то // продолжаем ее обработку, // чтобы получить информацию // об этой личности if ($node->tagname=='person')< // Создаем массив, куда // будем собирать информацию // о рассматриваемой личности $currentPers = array(); // Получаем id личности, // который хранится в атрибуте 'id' $currentPers['id'] = $node->get_attribute('id'); // Получаем массив потомков // . Это вся // информация о личности // (, и т.д.) $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 "
"; > > ?>

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

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

. $str = $currentPers["email"]; if ($currentPers["name"] == "Иван Иванов" ) echo "Здравствуйте, Иван! " . "Ваш e-mail $str"; .

Добавление новых элементов в XML-документ

Далее разберем задачу, как можно добавить в нашу базу данных новую личность средствами php.

Читайте также:  Полив приствольных кругов деревьев

Сначала нужно скопировать описание личности (считаем, что все личности описываются с помощью стандартного набора характеристик, как в файле persons.xml ). Это делается с помощью метода DomNode->clone_node() . Таким образом, мы клонируем элемент и все его внутренние элементы (содержание тегов не копируется).

Потом можно установить какие-нибудь значения для элементов описания личности. Например, задать имя человека, дату его рождения и т.п. В конце нужно записать полученное описание личности в качестве потомка корневого элемента в дерево DOM с помощью метода DomNode->append_child(new_node) , где в качестве параметра передается созданный объект (новый узел).

В PHP до версии 4.3 перед добавлением потомка к узлу с помощью данной функции этот потомок сначала копировался. Таким образом, новый узел являлся новой копией, которая могла изменяться без изменения узла, переданного как параметр в эту функцию. В более поздних версиях PHP новый узел удаляется из существующего контекста, если он уже есть в дереве. Такое поведение соответствует спецификациям W3C.

Для удаления узла можно воспользоваться методом, применив его к узлу, который требуется удалить, т.е. DomNode->unlink_node() .

// Для того чтобы добавить описание // новой личности, нужно знать, // как описывается каждая личность. // Выбираем элемент person, // который содержит описание личности $elements = $dom->get_elements_by_tagname("person"); $element = $elements[0]; //вычисляем родителя и потомков $parent = $element->parent_node(); $children = $element->child_nodes(); // клонируем элемент person $person = $element->clone_node(); // устанавливаем новой // личности идентификатор $attr = $person->set_attribute("id", "30"); // если у личности были потомки, // то их тоже надо клонировать foreach ($children as $child)< //клонируем ребенка $node = $child->clone_node(); //получаем массив внуков $grand_children = $child->child_nodes(); // если ребенок имеет потомков, //т.е. массив внуков не пуст, то if (count($grand_children)<>1)< //клонируем каждого внука //и присоединяем к уже //клонированному ребенку foreach($grand_children as $grand_child)< $lastnode = $grand_child->clone_node(); //записываем в нужные теги //подходящие значения if ($grand_child->tagname=="first") $cont = $lastnode->set_content("Nina"); if ($grand_child->tagname=="last") $cont = $lastnode->set_content("Saveljeva"); if ($grand_child->tagname=="day") $cont = $lastnode->set_content("7"); if ($grand_child->tagname=="month") $cont = $lastnode->set_content("06"); if ($grand_child->tagname=="year") $cont = $lastnode->set_content("1981"); $newlastnode = $node->append_child($lastnode); > > if ($child->tagname=="email") < $cont = $node->set_content("help@intuit.ru"); > $newnode2 = $person->append_child($node); > $newnode = $parent->append_child($person); //dump_mem создает XML-документ из dom //представления echo "
"; $xmlfile = $dom->dump_mem(true); // посмотрим в браузере, // что получилось echo htmlentities($xmlfile); echo "
"; // запишем полученный XML-файл // в файл "test.xml" $h = fopen("test.xml","a"); if (!fwrite($h, $xmlfile)) < print "Cannot write " . "to file ($filename)"; exit; >>

Заключение

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

Читайте также:  Каким деревом делать парную

Источник

Взаимодействие 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 -файлов, тоже становятся узлами.

 $root = $dom->document_element(); // Получаем массив потомков // родительского узла // (в нашем случае это массив ) $nodes = $root->child_nodes(); print_r($nodes); echo "
"; // Начинаем обработку каждого // узла в массиве foreach($nodes as $node)< // Если текущий узел – один // из узлов , то // продолжаем ее обработку, // чтобы получить информацию // об этой личности if ($node->tagname=='person')< // Создаем массив, куда // будем собирать информацию // о рассматриваемой личности $currentPers = array(); // Получаем id личности, // который хранится в атрибуте 'id' $currentPers['id'] = $node->get_attribute('id'); // Получаем массив потомков // . Это вся // информация о личности // (, и т.д.) $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 "
"; > > ?>

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

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

. $str = $currentPers["email"]; if ($currentPers["name"] == "Иван Иванов" ) echo "Здравствуйте, Иван! " . "Ваш e-mail $str"; .

Добавление новых элементов в XML-документ

Далее разберем задачу, как можно добавить в нашу базу данных новую личность средствами php.

Сначала нужно скопировать описание личности (считаем, что все личности описываются с помощью стандартного набора характеристик, как в файле persons.xml ). Это делается с помощью метода DomNode->clone_node() . Таким образом, мы клонируем элемент и все его внутренние элементы (содержание тегов не копируется).

Читайте также:  Можно ли дерево мыть водой

Потом можно установить какие-нибудь значения для элементов описания личности. Например, задать имя человека, дату его рождения и т.п. В конце нужно записать полученное описание личности в качестве потомка корневого элемента в дерево DOM с помощью метода DomNode->append_child(new_node) , где в качестве параметра передается созданный объект (новый узел).

В PHP до версии 4.3 перед добавлением потомка к узлу с помощью данной функции этот потомок сначала копировался. Таким образом, новый узел являлся новой копией, которая могла изменяться без изменения узла, переданного как параметр в эту функцию. В более поздних версиях PHP новый узел удаляется из существующего контекста, если он уже есть в дереве. Такое поведение соответствует спецификациям W3C.

Для удаления узла можно воспользоваться методом, применив его к узлу, который требуется удалить, т.е. DomNode->unlink_node() .

// Для того чтобы добавить описание // новой личности, нужно знать, // как описывается каждая личность. // Выбираем элемент person, // который содержит описание личности $elements = $dom->get_elements_by_tagname("person"); $element = $elements[0]; //вычисляем родителя и потомков $parent = $element->parent_node(); $children = $element->child_nodes(); // клонируем элемент person $person = $element->clone_node(); // устанавливаем новой // личности идентификатор $attr = $person->set_attribute("id", "30"); // если у личности были потомки, // то их тоже надо клонировать foreach ($children as $child)< //клонируем ребенка $node = $child->clone_node(); //получаем массив внуков $grand_children = $child->child_nodes(); // если ребенок имеет потомков, //т.е. массив внуков не пуст, то if (count($grand_children)<>1)< //клонируем каждого внука //и присоединяем к уже //клонированному ребенку foreach($grand_children as $grand_child)< $lastnode = $grand_child->clone_node(); //записываем в нужные теги //подходящие значения if ($grand_child->tagname=="first") $cont = $lastnode->set_content("Nina"); if ($grand_child->tagname=="last") $cont = $lastnode->set_content("Saveljeva"); if ($grand_child->tagname=="day") $cont = $lastnode->set_content("7"); if ($grand_child->tagname=="month") $cont = $lastnode->set_content("06"); if ($grand_child->tagname=="year") $cont = $lastnode->set_content("1981"); $newlastnode = $node->append_child($lastnode); > > if ($child->tagname=="email") < $cont = $node->set_content("help@intuit.ru"); > $newnode2 = $person->append_child($node); > $newnode = $parent->append_child($person); //dump_mem создает XML-документ из dom //представления echo "
"; $xmlfile = $dom->dump_mem(true); // посмотрим в браузере, // что получилось echo htmlentities($xmlfile); echo "
"; // запишем полученный XML-файл // в файл "test.xml" $h = fopen("test.xml","a"); if (!fwrite($h, $xmlfile)) < print "Cannot write " . "to file ($filename)"; exit; >>

Заключение

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

Источник

Оцените статью