simple xml parser php

Simple xml parser php

Пример #1 Файл example.php с XML строкой

Таким образом, это язык. Это всё равно язык программирования. Или
это скриптовый язык? Все раскрывается в этом документальном фильме,
похожем на фильм ужасов.

SimpleXML пользоваться очень просто! Попробуйте получить какую-нибудь строку или число из базового XML-документа.

Пример #2 Получение части документа

Результат выполнения данного примера:

В PHP получить доступ к элементу в XML документе, содержащим в названии недопустимые символы (например, дефис), можно путём заключения данного имени элемента в фигурные скобки и апострофы.

Пример #3 Получение строки

Результат выполнения данного примера:

Пример #4 Доступ к неуникальным элементам в SimpleXML

В том случае, если существует несколько экземпляров дочерних элементов в одном родительском элементе, то нужно применять стандартные методы итерации.

Результат выполнения данного примера:

Пример #5 Использование атрибутов

До сих пор мы только получали названия и значения элементов. SimpleXML может также получать доступ к атрибутам элемента. Получить доступ к атрибуту элемента можно так же, как к элементам массива ( array ).

Результат выполнения данного примера:

Пример #6 Сравнение элементов и атрибутов с текстом

Результат выполнения данного примера:

Пример #7 Сравнение двух элементов

Два элемента SimpleXMLElements считаются разными, даже если они указывают на один и тот же объект.

Результат выполнения данного примера:

Пример #8 Использование XPath

‘ // ‘ служит в качестве шаблона. Для указания абсолютного пути, опустите одну из косых черт.

Результат выполнения данного примера:

Пример #9 Установка значений

Данные в SimpleXML не обязательно должны быть неизменяемыми. Объект позволяет манипулировать всеми элементами.

Результат выполнения данного примера:

Пример #10 Добавление элементов и атрибутов

SimpleXML имеет возможность легко добавлять дочерние элементы и атрибуты.

Результат выполнения данного примера:

Пример #11 Взаимодействие с DOM

PHP может преобразовывать XML-узлы из SimpleXML в формат DOM и наоборот. Этот пример показывает, как можно изменить DOM-элемент в SimpleXML.

Результат выполнения данного примера:

User Contributed Notes 15 notes

There is a common «trick» often proposed to convert a SimpleXML object to an array, by running it through json_encode() and then json_decode(). I’d like to explain why this is a bad idea.

Additionally, because it is not designed for this purpose, the conversion to JSON and back will actually lose information in some situations. For instance, any elements or attributes in a namespace will simply be discarded, and any text content will be discarded if an element also has children or attributes. Sometimes, this won’t matter, but if you get in the habit of converting everything to arrays, it’s going to sting you eventually.

Of course, you could write a smarter conversion, which didn’t have these limitations, but at that point, you are getting no value out of SimpleXML at all, and should just use the lower level XML Parser functions, or the XMLReader class, to create your structure. You still won’t have the extra convenience functionality of SimpleXML, but that’s your loss.

Источник

Parsing XML with PHP (simplexml)

Firstly, may I point out that I am a newcomer to all things PHP so apologies if anything here is unclear and I’m afraid the more layman the response the better. I’ve been having real trouble parsing an xml file in to php to then populate an HTML table for my website. At the moment, I have been able to get the full xml feed in to a string which I can then echo and view and all seems well. I then thought I would be able to use simplexml to pick out specific elements and print their content but have been unable to do this.

The xml feed will be constantly changing (structure remaining the same) and is in compressed format. From various sources I’ve identified the following commands to get my feed in to the right format within a string although I am still unable to print specific elements. I’ve tried every combination without any luck and suspect I may be barking up the wrong tree. Could someone please point me in the right direction?!

Many, many thanks in advance,

5 Answers 5

Since no one followed my closevote, I think I can just as well put my own comments as an answer:

To get the values you can either use the implicit SimpleXml API and drill down to the wanted elements (like shown multiple times elsewhere on the site):

or you can use an XPath query to get at the wanted elements directly

Using XPath should be somewhat faster than iterating over the SimpleXmlElement object graph. Though it should be noted that the difference is in an neglectable area (read 0.000x vs 0.000y) for your feed. Still, if you plan to do more XML work, it pays off to familiarize yourself with XPath, because it’s quite powerful. Think of it as SQL for XML.

Источник

Средства парсинга XML в PHP

В личной практике задача разбирать XML средствами PHP возникла еще в 2005. Однако, при попытке разобраться и написать несложный скрипт, загружающий XML-файл в массив, я наткнулся на довольно серьёзную проблему – не существует нормальных программных средств и бинарных библиотек PHP для работы с XML. По мере работы с XML средствами PHP и эволюции PHP применялись различные технологии разбора XML кода, о них далее и пойдет речь.

Сперва приведу сводную таблицу совместимости средств PHP и библиотек XML.

simple xml parser php. Смотреть фото simple xml parser php. Смотреть картинку simple xml parser php. Картинка про simple xml parser php. Фото simple xml parser php

Самым совместимым оказался SAX (Simple API for XML), он поддерживается даже в библиотеке EXPAT имеющейся во всех версиях PHP 4 и выше. Однако его возможности и способы применения вызвали резко негативную реакцию – нет возможности модификации XML, крайне громоздкий и сложный код с большим количеством мест для потенциальных ошибок.

DOMXML ужасная вещь, т.к. существовала в виде дополнительных экспериментальных библиотек для PHP 4. В PHP 5 не включена, т.к. PHP 5 по умолчанию обладает более универсальным средством DOM (Стандарт W3C DOM level 3). DOM наиболее документирован (English PHP & W3C) и завершен, однако не включен в PHP 4, т.к. был разработан только к началу 2006. Если выбор станет DOM или PHP4, однозначно следует сказать DOM, т.к. на сегодняшний день PHP 5 имеется у любого уважающего себя хостинг провайдера. Тем более у разработчика, есть возможность писать PHP 4 совместимый код, т.к. PHP 4 обладает базовой DOM и она поддерживает некоторые основные функции новой DOM.

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

В Рунете небыло никакой более-менее полезной литературы на тот момент (осень 2007), все разработчики наповал использовали SAX (часто даже свои библиотеки базирующиеся на SAX) либо DOMXML. О DOM ещё мало кто слышал, а те, кто слышал, отказывались от использования в пользу более старого и менее стандартного, но более привычного DOMXML. Таким образом, имелся крайне низкий уровень реализации и переносимость существующих WEB решений использующих XML. Решение использовать новое, удобное, одобренное W3C средство DOM, было единственно правильным. DOM в PHP по его совместимости и взаимопониманию идентичен DOM’у в JS.

Проведем сравнительный анализ производительности SAX PHP 4 и DOM PHP 5. Будет произведен замер времени разбора следующего XML-файла.

simple xml parser php. Смотреть фото simple xml parser php. Смотреть картинку simple xml parser php. Картинка про simple xml parser php. Фото simple xml parser php

$GLOBALS[‘sax’][‘links’] = array(); // В этом массиве будут храниться блоки ссылок, полученные из XML файла
$GLOBALS[‘sax’][‘current_linksblock’]=null;// Текущий блок ссылок. Используется в процессе импорта данных
$GLOBALS[‘sax’][‘page_r’] =0;
$GLOBALS[‘sax’][‘page_i’] =-1;
$GLOBALS[‘sax’][‘link_r’] =0;
$GLOBALS[‘sax’][‘link_i’] =-1;
$GLOBALS[‘sax’][‘index’] =null;// Текущий индекс в массиве ссылок.
// Используется в процессе импорта данных

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

Приведем 2 метода разбора того же XML файла, базирующиеся на DOM PHP 5.
Метод 1
/* here we must specify the version of XML : i.e: 1.0 */
$xml = new DomDocument(‘1.0’);
$xml->load($link_file);

Метод использует физическую безадресную навигацию по дереву XML документа.

Метод 2
/* here we must specify the version of XML : i.e: 1.0 */
$xml = new DomDocument(‘1.0’);
$xml->load($link_file);

Метод использует ассоциативно-адресную навигацию по дереву XML документа.
В заключении замечу, что все три алгоритма в результате получают абсолютно идентичные массивы данных:

simple xml parser php. Смотреть фото simple xml parser php. Смотреть картинку simple xml parser php. Картинка про simple xml parser php. Фото simple xml parser php

Тесты производительности алгоритмов производились с учетом следующих условий:
Платформа AMD Athlon(tm) 64 X2 Dual Core Processor 4200+, DDR 2 1024 MB.
Веб-сервер Windows NT 5.1 build 2600, Apache/1.3.33 (Win32) PHP/5.1.6.

simple xml parser php. Смотреть фото simple xml parser php. Смотреть картинку simple xml parser php. Картинка про simple xml parser php. Фото simple xml parser php
simple xml parser php. Смотреть фото simple xml parser php. Смотреть картинку simple xml parser php. Картинка про simple xml parser php. Фото simple xml parser php
simple xml parser php. Смотреть фото simple xml parser php. Смотреть картинку simple xml parser php. Картинка про simple xml parser php. Фото simple xml parser php

График производительности позволяет сделать следующие заключения: SAX наиболее стабилен и его производительность не зависит ни от положения в теле программы, ни от нагрузки на сервер.
Рассмотрим среднеквадратичные показатели производительности для каждой группы тестов.

simple xml parser php. Смотреть фото simple xml parser php. Смотреть картинку simple xml parser php. Картинка про simple xml parser php. Фото simple xml parser php

1-SAX Произв 1
2-DOM 1 Произв 2
3-DOM 2 Произв 3
Make — режим сборки, Run 10 times — режим нагрузки.

1)Make 2-3-1(порядок следования)
2)Run 10 times 2-3-1(порядок следования)
3)Make 3-2-1(порядок следования)
4)Run 10 times 3-2-1(порядок следования)
5)Make 1-2-3(порядок следования)
6)Run 10 times 1-2-3(порядок следования)
7)Make 1-3-2(порядок следования)
8)Run 10 times 1-3-2(порядок следования)

Очевидно, что наиболее важным на данном этапе анализа является выявление наиболее производительного метода разбора XML основанного на DOM, SAX не рассматриваем, т.к. его отставание и недостатки очевидны.
Напомню, метод 1 использует физическую безадресную навигацию по дереву XML документа, менее удобочитаем, чем метод 2, который использует ассоциативно-адресную навигацию по дереву XML документа.
Для нас наиболее важны режимы результаты производительности при режимах нагрузки, такими являются четные тесты:

simple xml parser php. Смотреть фото simple xml parser php. Смотреть картинку simple xml parser php. Картинка про simple xml parser php. Фото simple xml parser php

Тесты 2 и 6, тесты в которых метод 1 идет первым, тесты 4 и 8, тесты в которых метод 2 идет первым.

Из графика следует, что при своем удобстве метод 2 достигает наивысших показателей производительности, только при многочисленном использовании XML в программе.

Метод 1, при меньшей лаконичности и пиковой производительности относительно метода 2, является более стабильным в использовании для разбора в единственном месте работы PHP скрипта.

Таким образом, переход на DOM PHP 5, в независимости от способа разбора XML документа, вполне оправдан, как по удобству кода, так и по производительности, тем более, с учетом того, что в настоящее время PHP 4 практически не используется.

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

Источник

SimpleXML. Пример расширенного использования

Простой пример использования

object(SimpleXMLElement)[1]
public ‘@attributes’ =>
array
‘name’ => string ‘хлеб’ (length=8)
‘preptime’ => string ‘5’ (length=1)
‘cooktime’ => string ‘180’ (length=3)
public ‘title’ => string ‘Простой хлеб’ (length=23)
public ‘ingredient’ =>
array
0 => string ‘Мука’ (length=8)
1 => string ‘Дрожжи’ (length=12)
2 => string ‘Тёплая вода’ (length=21)
3 => string ‘Соль’ (length=8)
public ‘Instructions’ =>
object(SimpleXMLElement)[2]
public ‘step’ =>
array
0 => string ‘Смешать все ингредиенты и тщательно замесить.’ (length=84)
1 => string ‘Закрыть тканью и оставить на один час в тёплом помещении.’ (length=104)
2 => string ‘Замесить ещё раз, положить на противень и поставить в духовку.’ (length=113)

Как видите все достаточно прозрачно и никакая документация не нужна. Но что будет, если скормить этому классу:

Сложный пример

Теперь наш код выведет не всю информацию о документе.
Не буду приводить полный вывод. Скажу лишь, что в выводе отсутствуют узлы ss:Worksheet

Получение узла ss:Worksheet
Способ первый. XPath
Способ второй. NS

xmlns=«urn:schemas-microsoft-com:office:spreadsheet»
xmlns:xsi=«www.w3.org/2001/XMLSchema-instance»
xmlns:x=«urn:schemas-microsoft-com:office:excel»
xmlns:x2=«schemas.microsoft.com/office/excel/2003/xml»
xmlns:ss=«urn:schemas-microsoft-com:office:spreadsheet»
xmlns:o=«urn:schemas-microsoft-com:office:office»
xmlns:html=«www.w3.org/TR/REC-html40»
xmlns:c=«urn:schemas-microsoft-com:office:component:spreadsheet»

Для доступа к атрибутам также понадобится явно указывать ns.

PS. Некоторые сложности добавляет еще тот факт, что в SimpleXML большинство методов имеют итерационные свойства и не всегда можно использовать функции var_dump, print_r, etc…
PSPS: Возможно для Вас эта заметка будет бесполезной, но столкнувшись с проблемой перерыл достаточно много инфы, примеров не было…

Источник

SimpleXML Functions

Table of Contents

User Contributed Notes 37 notes

If you are looking to use SimpleXML for anything but reading XML documents, you should really reconsider, and use the XML DOM library. By the time you get enough utilities implemented in DOM to handle all the set backs in SimpleXML, you will have defeated the purpose of using SimpleXML. There are a few reasons for this, and there are already many workrounds, but the primairy issues are this

1) No complex node assignment. You cannot switch nodes or replace them.

2) No appending new child nodes

Other than that, its a great tool for reading docs.

I had a problem with entities.

My first solution:
I saved Data that way:
$ENTRY_->
addchild(‘Nachricht’,htmlentities($_POST[«blog»]));

Had Entities in the XML-File like:

And I loaded the Data that way:
html_entity_decode($ENTRY->Nachname);

But after saving and
loading the xml-file the entity-entry

disappeared. strange.

My second solution:
With saving the Data this way:
$ENTRY_->
addchild(‘Nachricht’,htmlentities(htmlentities($_POST[«blog»])));

I can now load it with html_entity_decode without the
entity-entry in the XML-file!
I tested it with äöü.

If you are having trouble accessing CDATA in your simplexml document, you don’t need to str_replace/preg_replace the CDATA out before loading it with simplexml.

You can do this instead, and all your CDATA contents will be merged into the element contents as strings.

$xml = simplexml_load_file($xmlfile,
‘SimpleXMLElement’, LIBXML_NOCDATA);

This is a slight adjustment to http://www.php.net/manual/en/ref.simplexml.php#103617 ‘s function.
The function given by them would convert a simpleXML to an array but only at the highest level. Once you add the is_array check with the is_object it should convert each level to an array (well it did for me through 3 levels).

A simple implementation:
You can inform a direct XML in text format to the function.

Contrary to other notes posted here, SimpleXML *DOES NOT* properly handle non-UTF8 encoded XML documents.

A proper «iso-8859-1» declared and encoded XML document will not parse with SimpleXML for PHP 5.2.17 or 5.5.1 when using extended characters (that is, byte values greater than 127)

DOMDocument, on the other hand, will correctly parse incoming iso-8859-1 XML documents and can also be used to perform character translation to UTF8:

$dom = new DOMDocument();

It doesn’t mention this anywhere, but creationg a new SimpleXMLElement object from a non-valid string throws an exception. It looks ugly in the php log as it dumps the stack in multiple lines.

If you want to access an element that has a dash in its name, (as is common with the XML documents provided by the Library of Congress, as well as the NWS) you will need to handle it a little bit differently.

You can either use XPATH, which works fine, but will return an array of results every time, even if there is a single result.
eg.

On a only partially related note, dealing with SimpleXML is one of the only times I have employed casting with PHP. While iterating (foreach) through the valid times, echo’ing the element worked great (it merely echo’ed the apropriate time), assigning it to another variable resulted in a SimpleXML object containing the time to be assigned, rather than just the time itself. This was resolved by casting the time to a string:

Note that SimpleXML expects to both read and output XML in UTF-8 encoding. You’ll need to add a line such as this at the top of your input XML file if it isn’t saved in UTF-8 (adjust to whatever encoding used):

On the output side of things, if you’re not serving/handling UTF-8, you’ll need to use utf8_decode() [red. but that will only work for ISO-8859-1, not other encodings]. Common mistake: http://bugs.php.net/bug.php?id=28154

SimpleXML handles namespaces, but it’s not documented very well here at all.

If you wanted to parse, say, an open office manifest file or a piece of RDF/XML, you have to get elements and attributes by the namespace url.

SimpleXML is really nice for loading/converting XML data into native PHP data structures. I was considering crude searching of SVG for the width/height and since it really is an XML file. I found a SUPER easy method for parsing out the information I wanted:

// putting incomplete SVG data inline for readability
$RawXML =

fix the function i posted before, have a wrong quote placement

It does not say in the docs, but SimpleXML will convert all text into UTF-8, if the source XML declaration has another encoding. Eg, if the source has the following XML decl:

all the text in the resulting SimpleXMLElement will be in UTF-8 automatically.

If the SimpleXMLObject contains an array, adding is_array() allows the function to keep digging for Objects.

When creating a new XML document and adding text with umlauts and such

Use htmlentities () while adding Umlauts & co to solve the «problem»

Merge two xml only with SimpleXML :

As of PHP 5.1.4, trying to iterate on a non-existent node will actually create that node.

You might think it is a bug, but PHP developers seam to consider it as a feature : http://bugs.php.net/bug.php?id=39164

A quick snippet which converts XML Object into array:

An alternative to processing large XML files is the XMLReader class, which operates in streaming mode, of which an excellent tutorial is presented here:
http://www.ibm.com/developerworks/library/x-pullparsingphp.html

Sometimes it’s nice to mix up data storage types. This is a very simple SQL to XML converter. Feed it a SQL query and it outputs the result in XML.

The first paramater should be a mysql_query result
(optional)The second is the xml name for each row (i.e the second depth of XML)
(optional)The third is the name of the XML document, the root name

Merge two xml only with SimpleXML :
Function corrected if note containe only value.

If you need to do math calculations on values extracted from simplexml document, you might need to cast the value as float to prevent precision loss. Here is an example:

//Calculated on a string, no problem
echo «-123.45» + «-123.45» ;

«echo var_dump($x);» will output this

object(SimpleXMLElement)#3 (1) <
[0]=>
string(7) «-123.45»
>

I opened a bug request on php but here is the answer they gave me:

The behavior is defined by the engine not the extension. When performing mathematical operations on objects, they are treated as integers. It is up to the user to cast the object to the appropriate type to maintain proper precision.

Some text, a link, more text

Memory leak when setting attributes as in example (#Example 2134. Setting values)

This probably goes unnoticed in web scripts (unless you do a LOT of xml manipulations), but I ran into this in my standalone script that processes a large number of XML files.

The following code will eat up memory quite fast:

I just wanna add an additional to
«Append/combine/merge one simplexml to another»
The parent should has attributes too.

?>

I have aproblem to assign an object into a variable used as an object later, Then i found the code above, it solve half of my problem. I have it should have the parent name assign too but it didnt. Any better code?

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *