Php parsing xml to array

Работаем с XML как с массивом, на PHP

Всем привет. Хочу поделиться своим опытом в парсинге XML, хочу рассказать об инструменте который мне в этом помогает.

XML ещё жив и иногда его приходиться парсить. Особенно если вы работаете со СМЭВ (привет всем ребятам для которых «ФОИВ» не пустой звук 🙂 ).

Цели у такого парсинга могут быть самые разные, от банального ответа на вопрос какое пространство имён используется в xml-документе, до необходимости получить структурированное представление для документа вцелом.

Инструмент для каждой цели будет свой. Пространство имён можно найти поиском подстроки или регулярным выражением. Что бы сделать из xml-документа структурированное представление (DTO) — придётся писать парсер.

Для работы с XML в PHP есть пара встроенных классов. Это XMLReader и SimpleXMLElement.

XMLReader

С помощью XMLReader парсинг будет выглядеть примерно так :

$reader = (new XMLReader()); $reader->XML($content); while ($reader->read()) < $this->parse($reader); >

Внутри метода parse(XMLReader $xml) будут бесконечные:

$name = $xml->name; $value = $xml->expand()->textContent; $attrVal = $xml->getAttribute('attribute'); $isElem = $xml->nodeType === XMLReader::ELEMENT;

Для небольших документов или когда нам из всего документа надо только пару элементов, это приемлемо, на больших объёмах — начинает в глазах рябить от однообразного кода, плюс совесть грызёт за оверхэд от перебора всех элементов документа.

SimpleXMLElement

Провести анализ только нужных элементов помогает SimpleXMLElement. Этот класс из XML-документа делает объект, у которого все элементы и атрибуты становятся свойствами, то есть появляется возможность работать только с определёнными элементами, а не со всеми подряд, пример:

$document = new SimpleXMLElement($content); /* имя корневого элемента */ $name = $document->getName(); /* получить произвольный элемент */ $primary = $document ->Message ->ResponseContent ->content ->MessagePrimaryContent ?? null; /* получить элементы определённого пространства имён */ $attachment = $primary ->children( 'urn://x-artefacts-fns-zpvipegr/root/750-08/4.0.1' ) ->xpath('tns:Вложения/fnst:Вложение')[0]; /* получить значение элемента */ $fileName = $attachment ->xpath('//fnst:ИмяФайла')[0] ->__toString();

Удобно, да не совсем. Если имя элемента на кириллице, то обратиться к нему через свойство не получиться, придётся использовать SimpleXMLElement::xpath(). С множественными значениями так же приходиться работать через SimpleXMLElement::xpath(). Кроме того SimpleXMLElement имеет свои особенности и некоторые вещи далеко не очевидны.

Converter

Есть способ проще. Достаточно XML-документ привести к массиву. В работе с массивами нет ни каких подводных камней. Массив из XML делается в пару строчек кода:

$xml= ccc  0000 XML; $fabric = (new NavigatorFabric())->setXml($xml); $converter = $fabric->makeConverter(); $arrayRepresentationOfXml = $converter->toArray();

Каждый XML-элемент будет представлен массивом, состоящим в свою очередь, из трёх других массивов.

  • массив с индексом ‘*value’ содержит значение элемента,
  • ‘*attributes’ — атрибуты элемента,
  • ‘*elements’ — вложенные элементы.
/* 'b' => array ( '*value' => '0000', '*attributes' => array ( 'attr4' => '55', ), '*elements' => array ( 'c' => array ( ), ), ), */

Если элемент множественный, то есть встречается в документе несколько раз подряд, то все его вхождения будут в массиве с индексом ‘*multiple’.

$xml= first occurrence second occurrence  XML; /* 'doc' => array ( 'qwe' => array ( '*multiple' => array ( 0 => array ( '*value' => 'first occurrence', ), 1 => array ( '*value' => 'second occurrence', ) ) ) ) */

XmlNavigator

Если от работы с XML-документов как с массивом, у вас в глазах рябит от квадратных скобочек, то XmlNavigator — это ваш вариант, создаётся так же в две строки кода.

/* документ */ $xml = 666 element value     0     XML; $fabric = (new NavigatorFabric())->setXml($xml); $navigator = $fabric->makeNavigator();

XmlNavigator делает, то же самое что и Converter, но предоставляет API, и с документом мы работаем как с объёктом.

Читайте также:  Html border margin left

Имя элемента, метод name()

/* Имя элемента */ echo $navigator->name(); /* doc */

Значение элемента, метод value()

/* Значение элемента */ echo $navigator->value(); /* 666 */

Список атрибутов, метод attribs()

/* get list of attributes */ echo var_export($navigator->attribs(), true); /* array ( 0 => 'attrib', 1 => 'option', ) */

Значение атрибута, метод get()

/* get attribute value */ echo $navigator->get('attrib'); /* a */

Список вложенных элементов, метод elements()

/* Список вложенных элементов */ echo var_export($navigator->elements(), true); /* array ( 0 => 'base', 1 => 'valuable', 2 => 'complex', ) */

Получить вложенный элемент, метод pull()

/* Получить вложенный элемент */ $nested = $navigator->pull('complex'); echo $nested->name(); /* complex */ echo var_export($nested->elements(), true); /* array ( 0 => 'a', 1 => 'different', 2 => 'b', 3 => 'c', ) */

Перебрать все вхождения множественного элемента, метод next()

/* Получить вложенный элемент вложенного элемента */ $multiple = $navigator->pull('complex')->pull('b'); /* Перебрать все вхождения множественного элемента */ foreach ($multiple->next() as $index => $instance) < echo " name()>[$index]" . " => get('val')>;"; > /* b[0] => x; b[1] => y; b[2] => z; */

Все методы класса XmlNavigator

Класс XmlNavigator реализует интерфейс IXmlNavigator.

Из названий методов очевидно их назначение. Не очевидные были рассмотрены выше.

Как установить?

composer require sbwerewolf/xml-navigator

Заключение

В работе приходиться использовать сначала SimpleXMLElement — с его помощью из всего документа получаем необходимый элемент, и уже с этим элементом работаем через XmlNavigator.

$document = new SimpleXMLElement($content); $primary = $document ->Message ->ResponseContent ->content ->MessagePrimaryContent; $attachment = $primary ->children( 'urn://x-artefacts-fns-zpvipegr/root/750-08/4.0.1' ) ->xpath('tns:Вложения')[0]; $fabric = (new NavigatorFabric())->setSimpleXmlElement($attachment); $navigator = $fabric->makeNavigator();

Желаю вам приятного использования.

Эпилог

Конечно у вас могут быть свои альтернативы для работы с XML. Предлагаю поделиться в комментариях.

Читайте также:  Как загрузить пандас в питон

Конечно, не могу сказать, что XmlNavigator поможет с любым XML — не проверял, но с обычными документами, без хитростей в схеме документа, проблем не было.

Если вам важен порядок следования элементов, то придётся пользоваться XMLReader. Потому что SimpleXMLElement приводит документ к объекту, а у объекта нет такого понятия как порядок следования элементов.

Источник

Parse XML to an Array in PHP With SimpleXML

Sajal Soni

Sajal Soni Last updated Aug 12, 2020

In this post, you’ll learn how to parse XML into an array in PHP. SimpleXML is a PHP extension that makes this possible.

In your day-to-day PHP development, sometimes you’ll need to deal with XML content. Whether it’s exporting data as XML documents or processing incoming XML documents in your application, it’s always handy to have a library that can perform these operations smoothly. When it comes to dealing with XML in PHP, there are different methods to choose from. In fact, there are different extensions available in PHP that allow you to read and parse XML documents.

PHP’s XML parser is based on James Clark’s expat library, which is a stream-oriented XML library written in C. This XML parser library allows you to parse XML documents, but it’s not able to validate them. It’s event-based and stream-oriented, and thus it’s really useful when you’re dealing with very large XML files—but a little more complicated than it needs to be for small files.

The other option is the SimpleXML extension, which is one of the most popular extensions used by the PHP community to process XML documents. The SimpleXML extension allows you to parse XML documents very easily, just as if you were reading a file in PHP.

In this article, we’re going to use the SimpleXML extension to demonstrate how you could convert XML content into an array. If you want to follow along with the example in this article, make sure that you’ve installed the SimpleXML extension in your PHP installation.

The SimpleXML PHP Extension

The SimpleXML PHP extension provides a complete toolset which you can use to read, write and parse XML documents in your PHP applications. It’s important to note that the SimpleXML extension requires PHP 5 at a minimum. Also, it requires the libxml PHP extension.

Читайте также:  Сократить число до десятых python

The SimpleXML extension is enabled by default, but if you want to check if it’s enabled in your PHP installation, you can check it quickly by using the phpinfo() function.

The phpinfo Function

As you can see, you should see the SimpleXML section in the output of the phpinfo() function.

The SimpleXML extension provides different functions that you could use to read and parse XML content.

Loading an XML String or File With SimpleXML

For example, if you want to parse the XML file, you can use the simplexml_load_file() function. The simplexml_load_file() function allows you to read and parse the XML file in a single call. On the other hand, if you have an XML string which you want to convert into an XML document object, you can use the simplexml_load_string() function.

You could also use the file_get_contents() function to read the file contents and pass the resulting string to the simplexml_load_string() function, which eventually parses it into an object. Alternatively, if you prefer the object-oriented way, you could also use the SimpleXMLElement class and its utility methods to convert an XML string into an object.

In this article, we’re going to use the simplexml_load_file() function to read an XML file, and we’ll see how to convert it into an array. Next, we’ll go through a real-world example to demonstrate how to do this.

How to Convert XML to an Array With PHP

In this section, we’ll see how you can convert XML content into an array.

First of all, let’s quickly go through the steps that you need to follow to convert XML content into an array with the help of the SimpleXML extension.

  • Read the file contents and parse them. At the end of this step, the content is parsed and converted into the SimpleXMLElement object format. We’re going to use the simplexml_load_file() function to achieve this.
  • Next, you need to convert the SimpleXMLElement object into a JSON representation by using the json_encode() function.
  • Finally, you need to use the json_decode() function to decode the JSON content so that it eventually generates an array of all documents.

For demonstration purposes, let’s assume that we have an XML file as shown in the following snippet. We’ll call it employees.xml. It contains the basic details of all employees. Our aim is to convert it into an array that you could use for further processing.

Источник

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