Xmlreader php вложенные элементы
Как использовать XMLReader в PHP?
У меня есть следующий файл XML, файл довольно большой, и я не смог заставить simplexml открывать и читать файл, поэтому я пытаюсь использовать XMLReader без успеха в php
Я, к сожалению, не нашел хорошего учебника по этому поводу для PHP и хотел бы узнать, как я могу получить содержимое каждого элемента для хранения в базе данных.
Все зависит от того, насколько велика единица работы, но я думаю, вы пытаетесь обрабатывать каждый узел
Для этого самым простым способом было бы использовать XMLReader для доступа к каждому узлу, а затем использовать SimpleXML для доступа к ним. Таким образом, вы сохраняете низкое потребление памяти, потому что вы обрабатываете один узел за раз, и вы все еще используете простоту использования SimpleXML. Например:
Быстрый обзор плюсов и минусов различных подходов:
Плюсы: быстрый, мало памяти
Минусы: чрезмерно трудно писать и отлаживать, требует много кода пользователя, чтобы сделать что-нибудь полезное. Код Userland медленный и подвержен ошибкам. Кроме того, он оставляет вам больше строк кода для
Плюсы: не использует много памяти (только память, необходимая для обработки одного узла), и SimpleXML, как следует из названия, очень проста в использовании.
Минусы: создание объекта SimpleXMLElement для каждого узла происходит не очень быстро. Вам действительно нужно сравнить его, чтобы понять, является ли это проблемой для вас. Однако даже скромная машина сможет обрабатывать тысячу узлов в секунду.
Плюсы: использует примерно столько же памяти, как SimpleXML, а XMLReader :: expand () быстрее, чем создание нового элемента SimpleXMLElement. Мне хотелось бы использовать simplexml_import_dom() но в этом случае он не работает
Минусы: DOM раздражает работать. Это на полпути между XMLReader и SimpleXML. Не так сложно и неудобно, как XMLReader, но в несколько световых лет от работы с SimpleXML.
Мой совет: напишите прототип с SimpleXML, посмотрите, работает ли он для вас. Если производительность имеет первостепенное значение, попробуйте DOM. Оставайтесь как можно дальше от XMLReader. Помните, что чем больше кода вы пишете, тем выше вероятность того, что вы вводите ошибки или вводите регрессии производительности.
Для xml, отформатированных с атрибутами …
Большая часть моей работы по анализу XML тратится на извлечение самородков полезной информации из грузовиков XML (Amazon MWS). Таким образом, мой ответ предполагает, что вы хотите получить только конкретную информацию, и знаете, где она находится.
Я считаю, что самый простой способ использования XMLReader – узнать, какие теги я хочу получить из них и использовать. Если вы знаете структуру XML и у нее много уникальных тегов, я считаю, что использование первого случая – это просто. Случаи 2 и 3 – это просто показать вам, как это можно сделать для более сложных тегов. Это очень быстро; У меня есть обсуждение скорости над тем, что является самым быстрым парсером XML в PHP?
Самое важное, что нужно учитывать при анализе на основе тегов, это использовать if ($myXML->nodeType == XMLReader::ELEMENT) <. – который проверяет, что мы имеем дело только с открытием узлов и а не пробельные или закрывающие узлы или что-то еще.
XMLReader хорошо документирован на PHP-сайте . Это XML Pull Parser, что означает, что он используется для итерации через узлы (или DOM-узлы) данного XML-документа. Например, вы можете пройти весь документ, который вы указали так:
Тогда вам решать, как обращаться с узлом, возвращаемым XMLReader :: expand () .
Принятый ответ дал мне хороший старт, но принес больше классов и больше обработки, чем мне хотелось бы; так это моя интерпретация:
Этот вопрос давно ушел, но я только что нашел его. Слава Богу.
Моя проблема в том, что я должен прочитать файл ONIX (данные книги) и сохранить его в нашей базе данных. Я использую simplexml_load раньше, и хотя он использовал много памяти, но все еще хорошо для относительно небольшого файла (до 300 МБ). Вне этого размера это катастрофа для меня.
После прочтения, особенно интерпретации Фрэнсиса Льюиса, я использую комбинацию xmlreader и simplexml. Результат является исключительным, использование памяти невелико и вставляет его в базу данных достаточно быстро для меня.
Я боюсь, что использование XmlReader :: expand () может потреблять довольно много ОЗУ, когда поддерево не так мало. Я не уверен, что это хорошая альтернатива XmlReader. Однако я согласен с тем, что XmlReader действительно слаб и не очень подходит для обработки сложных вложенных XML-деревьев. Мне действительно не нравятся две вещи: во-первых, этот текущий узел не имеет своего пути в дереве XML, доступном как свойство, во-вторых, что при чтении узлов не удается запустить XPath-подобную обработку. Конечно, реальный запрос XPath будет очень трудоемким для больших XML, но вместо этого можно использовать «крючки пути» – например, когда текущий путь к элементу соответствует корневому поддереву, запускается функция / метод PHP. Таким образом, несколько лет назад я разработал свои собственные классы поверх XmlReader. Они не идеальны, и, возможно, я бы лучше написал сегодня, но все же может быть полезен кому-то:
Я сам создаю XML-путь ‘node1 / node2’, а затем использовал крючки с совпадениями PCRE, которые менее эффективны, чем XPath, однако для моих нужд было достаточно. Я обработал довольно сложный большой XML с этими классами.
Класс XMLReader
(PHP 5 >= 5.1.0, PHP 7)
Введение
Расширение XMLReader — синтаксический анализатор XML. Класс-читатель выступает в качестве курсора, следует по потоку документа и останавливается на каждом узле на этом пути.
Обзор классов
Свойства
Количество атрибутов в узле
Базовый URI узла
Глубина узла в дереве, начиная с 0
Показывает, есть ли у узла атрибуты
Показывает, имеет ли узел текстовое значение
Показывает, является ли атрибутом по умолчанию из DTD
Показывает, является ли узел пустым тегом
Локальное имя узла
Полностью определенное имя узла
URI пространства имён связанный с узлом
Префикс пространства имён связанный с узлом
Текстовое значение узла
Контекст xml:lang, в котором находится узел
Предопределенные константы
Типы узлов XMLReader
XMLReader::ELEMENT
XMLReader::ATTRIBUTE
XMLReader::TEXT
XMLReader::CDATA
XMLReader::ENTITY_REF
Узел ссылки на сущность
XMLReader::ENTITY
Узел объявления объекта
XMLReader::PI
Узел инструкций обработки
XMLReader::COMMENT
XMLReader::DOC
XMLReader::DOC_TYPE
Узел типа документа
XMLReader::DOC_FRAGMENT
Узел фрагмента документа
XMLReader::NOTATION
XMLReader::WHITESPACE
XMLReader::SIGNIFICANT_WHITESPACE
Существенный пробельный узел
XMLReader::END_ELEMENT
XMLReader::END_ENTITY
XMLReader::XML_DECLARATION
Узел XML объявления
Опции анализатора XMLReader
Загружать DTD, но не проверять
XMLReader::DEFAULTATTRS
Загружать DTD и атрибуты по умолчанию, но не проверять
XMLReader::VALIDATE
Загружать DTD и проверять при разборе
XMLReader::SUBST_ENTITIES
Заменять объекты и разворачивать ссылки
Содержание
- XMLReader::close — Закрыть ввод XMLReader
- XMLReader::expand — Возвратить копию текущего узла в виде объекта DOM
- XMLReader::getAttribute — Получить значение атрибута с определённым именем
- XMLReader::getAttributeNo — Получить значение атрибута по индексу
- XMLReader::getAttributeNs — Получить значение атрибута по localname и URI
- XMLReader::getParserProperty — Указывает, было ли определенное свойство установлено
- XMLReader::isValid — Показать, является ли разбираемый документ синтаксически правильным
- XMLReader::lookupNamespace — Найти пространство имён для префикса
- XMLReader::moveToAttribute — Переместить курсор к атрибуту с заданным именем
- XMLReader::moveToAttributeNo — Переместить курсор на атрибут по индексу
- XMLReader::moveToAttributeNs — Переместить курсор к именованному атрибуту
- XMLReader::moveToElement — Позиционировать курсор на родительском элементе текущего атрибута
- XMLReader::moveToFirstAttribute — Переместить позицию курсора на первый атрибут
- XMLReader::moveToNextAttribute — Переместить позицию курсора на следующий атрибут
- XMLReader::next — Переместить курсор на следующий узел, пропуская все поддеревья
- XMLReader::open — Установить URI, содержащий XML-документ для разбора
- XMLReader::read — Переместиться к следующему узлу в документе
- XMLReader::readInnerXML — Извлечь XML из текущего узла
- XMLReader::readOuterXML — Получить XML из текущего узла, включая сам узел
- XMLReader::readString — Прочитать содержимое текущего узла как строку
- XMLReader::setParserProperty — Устанавливает опцию парсера
- XMLReader::setRelaxNGSchema — Установить имя файла или URI для схемы RelaxNG
- XMLReader::setRelaxNGSchemaSource — Устанавливает данные, содержащие схему RelaxNG
- XMLReader::setSchema — Проверить документ, используя XSD
- XMLReader::XML — Установить данные, содержащие XML для разбора
Работа с XML в PHP
Здравствуйте, уважаемые читатели блога LifeExample, в этой статье «Работа с XML в PHP» я расскажу о том, как считывать, перезаписывать, удалять и производить php запись в xml файл. А так же о том, как в принципе быстро и удобно создать и поместить данные в xml разметку. Будучи студентом работая над своими проектами, я самостоятельно писал библиотеки для обработки XML документов. Я очень рад, что теперь мне не приходится пользоваться своими велосипедами т.к. есть готовые решения присутствующие в PHP по умолчанию.
Работа с XML в PHP — PHP запись в XML
Инструмент XMLWriter был создан специально для записи в XML формате. Один из важных его методов это startDocument(), который позволяет задать кодировку версии XML.
Попробуем создать простенький XML следующего вида:
Получить такой формат можно с помощью XMLWriter таки вот образом:
Как видите, Работа с XML в PHP, благодаря XMLWriter становится невероятно простой, и сильно облегчает задачи записи XML формата. Далее приведу маленький комплекс примеров о том, как осуществить, на php запись в xml. Например, задача поставлена — получить файл XML в следующем формате:
1 / id>
2013-04-19 10:56:03 / time>
$350 / total>
/ customer>
2 / id>
2013-04-23 13:43:41 / time>
$1456 / total>
/ customer>
/ purchase>
Чтобы получить такую структуру нужно выполнить ряд не хитрых методов класса XMLWriter.
Следующий пример покажет, как добавлять атрибуты к узлам XML дерева, согласитесь это довольно востребованная задача в проектах, где необходима работа с XML.
$1.00 / price>
3% / discount>
/ product>
$0.90 / price>
3% / discount>
/ product>
/ products>
С помощью XMLWriter, делается это так:
Работа с XML в PHP — Чтение и получение данных из XML
Ниже будет приведен пример чтения и получения данных из XML с использованием классов XMLReader и SimpleXMLElement. Читать будем уже имеющийся XML объект, который мы создали в примере №1 при PHP записи в XML.
XMLReader используется для получения заданного узла из XML.
// Чтение XML формата
$rxml = new XMLReader ( ) ; //Создание элемента для чтения
$rxml -> xml ( $nXML ) ; //Загрузка XML, $nXML — строка в формате XML
//Переместиться к первому элементу customer
while ( $rxml -> read ( ) && $rxml -> name !== ‘customer’ ) ;
//Получим значение поля total у второго узла дерева
while ( $rxml -> name === ‘customer’ ) <
//Чтение текущего дочернего через SimpleXMLElement
$node = new SimpleXMLElement ( $rxml -> readOuterXML ( ) ) ;
//Проверяем, номер элемента, если он равен 2 то это искомый элемент
if ( $node -> id == 2 ) <
$amountSpent = $node -> total ;
break ;
>
//Переместиться к следующему элементу customer
$rxml -> next ( ‘customer’ ) ;
>
Часто задача возникает в получении данных из XML по значению, какого либо атрибута. Давайте по примеру №2 из раздела PHP запись в XML, получим название, цену и скидку продукта по его атрибуту p >
$rxml = new XMLReader ( ) ;
$rxml -> xml ( $nXML2 ) ;
while ( $rxml -> read ( ) && $rxml -> name !== ‘product’ ) ; //Перемещаемся к первому продукту
$name = «» ;
$price = «» ;
$discount = «» ;
while ( $rxml -> name === ‘product’ ) <
if ( $rxml -> getAttribute ( «pid» ) == «315» ) //если p >
<
$node = new SimpleXMLElement ( $rxml -> readOuterXML ( ) ) ; //читаем значение элементов
$name = $node -> name ;
$price = $node -> price ;
$discount = $node -> discount ;
break ;
>
$rxml -> next ( ‘product’ ) ; //перемещаемся к следующему
>
echo «Продукт №315. Наименование: <$name>, цена: <$price>скидка: <$discount>» ;
Работа с XML в PHP — Добавление узлов дерева в существующий XML
Работая с XML в PHP, не редко приходится ломать голову над тем как добавить новый элемент в имеющуюся XML структуру. Используя XMLWriter и SimpleXMLElement сделать это очень легко:
Работа с XML в PHP — Перезапись элементов существующего XML
При активной работе с XML в PHP, приходится не только считывать и записывать элементы, но и редактировать имеющиеся. Перезапись существующего узла дерева XML может быть реализована следующим образом:
/**
* Перезапись узлов дерева XML формата.
*/
$productId = 314 ;
$parent = new DomDocument ;
// создаем новый элемент дома product
$parent_node = $parent -> createElement ( ‘product’ ) ;
//Добавляем атрибут
$attribute = $parent -> createAttribute ( «pid» ) ;
//устанавливаем значение
$attribute -> value = $productId ;
$parent_node -> appendChild ( $attribute ) ;
// Добавляем дочерний элементы
$parent_node -> appendChild ( $parent -> createElement ( ‘name’ , «Яблоко» ) ) ;
$parent_node -> appendChild ( $parent -> createElement ( ‘price’ , » $2 .00″ ) ) ;
$parent_node -> appendChild ( $parent -> createElement ( ‘discount’ , «1%» ) ) ;
//Вставляем созданные элементы в создаваемый ‘product’
$parent -> appendChild ( $parent_node ) ;
// Загружаем оригинальный XML формат
$dom = new DomDocument ;
$dom -> loadXML ( $nXML ) ;
// Находим имеющийся элемент с p >
$xpath = new DOMXpath ( $dom ) ;
$nodelist = $xpath -> query ( «/products/product[@p > <$productId>]» ) ;
$oldnode = $nodelist -> item ( 0 ) ;
// Импортируем созданый ранее элемент в текущее дерево
$newnode = $dom -> importNode ( $parent -> documentElement , true ) ;
// заменяем страрый элемент на новый
$oldnode -> parentNode -> replaceChild ( $newnode , $oldnode ) ;
// сохраняем XML
echo $dom -> saveXML ( ) ;
Работа с XML в PHP — Удаление элементов XML
Из всего выше рассмотренного, осталась только одна операция, без которой данную статью о работе с XML в PHP , нельзя считать завершенной – это удаление элементов. Удаление элементов самое легкое из всей связки операций. Ну что же, ломать – не стоить, давайте удалим один из продуктов.
//Удаление продукта Манго
//загрузим оригинальный формат XML
$productId = 315 ;
$dom = new DomDocument ;
$dom -> loadXML ( $nXML2 ) ;
// Найдем элемент который необходимо удалить
$xpath = new DOMXpath ( $dom ) ;
$nodelist = $xpath -> query ( «/products/product[@p > <$productId>]» ) ;
$oldnode = $nodelist -> item ( 0 ) ;
// Удаляем элемент
$oldnode -> parentNode -> removeChild ( $oldnode ) ;
echo $dom -> saveXML ( ) ;
Закрыть текущий элемент (тэг) в xmlwriter
Найдя время и отвлекшись от основного своего проекта, я всё-таки опубликовал действительно полезную статью «Работа с XML в PHP«, и надеюсь она пригодится в своих разработках. Пишите мне на e-mail, с какими задачами вы сталкиваетесь, и я попробую сформировать материал по их решению в следующих статьях
Читайте также похожие статьи:
Чтобы не пропустить публикацию следующей статьи подписывайтесь на рассылку по E-mail или RSS ленту блога.