Php как подключить xmlreader
Frontend / Backend developer
Парсинг XML с помощью XMLReader на PHP
XMLReader это потоковый XML парсер, способный обрабатывать большие объемы данных при низких затратах оперативной памяти.
XMLReader использует курсор для перемещения по структуре документа, без создания DOM дерева, как это делает, к примеру SimpleXML. Обрабатывать документы, конечно становится немного сложнее, но минимальные затраты драгоценной памяти и возможность обрабатывать огромные массивы данных, я думаю, перекрывают этот недостаток.
Самый простой пример использования XMLReader.
Предположим, у нас стоит задача импорта из XML в нашу базу данных.
Вот XML структура (файл example.xml) :
Для разбора этой, относительно несложной структуры, достаточно такого кода:
Таким образом, мы решили задачу об импорте из xml:
id | contact | number |
1 | kenny | 9(999)-999-99-99 |
2 | finny | 8(888)-888-88-88 |
Dive into XMLReader
С парсингом простых структур понятно, но что делать если есть структуры непростые? Писать каждый раз цикл чтения и кучу условий как-то не по взрослому, да и правки всего этотого кода в случае изменения структуры могут обернуться тем еще баттхёртом.
Итак, стояла задача обмена конфигурацией web-приложения с 1с. Обмен производится в виде XML документов с общими настройками приложения и ценообразования.
Вот пример конфигурационного xml файла, приходящего в приложение из 1с:
Как видите, уже на первых этапах разработки приложения, минимальный конфигурационный xml довольно объемный, и дальше он будет только расти, с добавлением фич ростом требований к web-приложению.
Конечно, можно было бы разработать функцию, выполняющую импорт данных, по аналогии с предыдущим примером, но, учитывая возможность изменений структуры, я пришел к выводу, что это было бы, мягко говоря, неоправдано и сложно-поддерживаемо.
Но довольно слов, приступим к коду:
Сперва нужно разработать общий базовый класс для оберток над этой библиотекой. Назовем наш абстрактный класс AbstractAdvertisementXMLReader.
Как видим, имеется защищенный от агрессивной внешней среды экземпляр XMLReader’а, хэш-массив результатов извлечения, а также контейнер событий.
В конструкторе мы пытаемся инициализировать XMLReader, и открыть с помощью него переданный путь к xml файлу.
Тут все достаточно просто и наглядно.
Теперь давайте реализуем необходимые акцессоры:
Реализация событийной модели:
В качестве параметров, подписчики дополнительно получают контекст, т.е. ссылку на вызывающий объект AbstractAdvertisementXMLReader (либо класс его наследующий).
Осталось добавить в этот класс щепотку базовой логики:
Вот и все, базовый класс полностью готов!
Далее я покажу как можно использовать все это безобразие.
Как видим, все просто и понятно.
Вот таким нехитрым способом можно парсить большие и достаточно сложные XML файлы.
Источник
Класс XMLReader
Введение
Обзор классов
Свойства
Количество атрибутов в узле
Глубина узла в дереве, начиная с 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
Заменять объекты и разворачивать ссылки
Содержание
User Contributed Notes 20 notes
Wrapper XMLReader class, for simple SAX-reading huge xml:
https://github.com/dkrnl/SimpleXMLReader
/**
* Simple XML Reader
*
* @license Public Domain
* @author Dmitry Pyatkov(aka dkrnl)
* @url http://github.com/dkrnl/SimpleXMLReader
*/
class SimpleXMLReader extends XMLReader
<
The «XML2Assoc» functions noted here should be used with caution. basically they are duplicating the functionality already present in SimpleXML. They may work but they won’t scale.
Their are two main uses cases for parsing XML, each suited to either XMLReader or SimpleXML.
1. SimpleXML is an excellent tool for easy access to an XML document tree using native PHP data types. It starts to flounder with massive (> 50M or so) XML documents, as it reads the entire document into memory before it can be processed. SimpleXML will just laugh at you then die when your server runs out of memory (or it will cause a load spike).
2. Aside from the reasoning behind massive XML documents, if you have to deal with massive XML documents, use XMLReader to process them. Don’t try and gather an entire XML document into a PHP data structure using XMLReader and a PHP xml2assoc() function, you are reinventing the SimpleXML wheel.
When parsing massive XML documents using XMLReader, gather the data you need to perform an operation then perform it before skipping to the next node. Do not build massive data structures from a massive XML document, your server (and it’s admins) will not like you.
(bool) true
(bool) false
Thanks rein_baarsma33 AT hotmail DOT com for bugfixes.
This is my new child of XML parsing method based on my and yours modification.
XML2ASSOC Is a complete solution for parsing ordinary XML
/**
* XML2Assoc Class to creating
* PHP Assoc Array from XML File
*
* @author godseth (AT) o2.pl & rein_baarsma33 (AT) hotmail.com (Bugfixes in parseXml Method)
* @uses XMLReader
*
*/
case XMLReader :: END_ELEMENT :
case XMLReader :: ELEMENT :
?>
[EDIT BY danbrown AT php DOT net: Fixes were also provided by «Alex» and (qdog AT qview DOT org) in user notes on this page (since removed).]
Источник
Как использовать 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) <. – который проверяет, что мы имеем дело только с открытием узлов и а не пробельные или закрывающие узлы или что-то еще.
Принятый ответ дал мне хороший старт, но принес больше классов и больше обработки, чем мне хотелось бы; так это моя интерпретация:
Этот вопрос давно ушел, но я только что нашел его. Слава Богу.
Моя проблема в том, что я должен прочитать файл ONIX (данные книги) и сохранить его в нашей базе данных. Я использую simplexml_load раньше, и хотя он использовал много памяти, но все еще хорошо для относительно небольшого файла (до 300 МБ). Вне этого размера это катастрофа для меня.
После прочтения, особенно интерпретации Фрэнсиса Льюиса, я использую комбинацию xmlreader и simplexml. Результат является исключительным, использование памяти невелико и вставляет его в базу данных достаточно быстро для меня.
Я боюсь, что использование XmlReader :: expand () может потреблять довольно много ОЗУ, когда поддерево не так мало. Я не уверен, что это хорошая альтернатива XmlReader. Однако я согласен с тем, что XmlReader действительно слаб и не очень подходит для обработки сложных вложенных XML-деревьев. Мне действительно не нравятся две вещи: во-первых, этот текущий узел не имеет своего пути в дереве XML, доступном как свойство, во-вторых, что при чтении узлов не удается запустить XPath-подобную обработку. Конечно, реальный запрос XPath будет очень трудоемким для больших XML, но вместо этого можно использовать «крючки пути» – например, когда текущий путь к элементу соответствует корневому поддереву, запускается функция / метод PHP. Таким образом, несколько лет назад я разработал свои собственные классы поверх XmlReader. Они не идеальны, и, возможно, я бы лучше написал сегодня, но все же может быть полезен кому-то:
Я сам создаю XML-путь ‘node1 / node2’, а затем использовал крючки с совпадениями PCRE, которые менее эффективны, чем XPath, однако для моих нужд было достаточно. Я обработал довольно сложный большой XML с этими классами.
Источник