Помогите с разбором XML в PHP

12
X
На сайте с 04.12.2018
Offline
280
651

Есть XML вида. 

<?xml version="1.0" encoding="UTF-8"?>
<shop>
        <offers>
                <offer>
                        <ID>53</ID>
                        <name>Название товара</name>
                        <vendor>Имя производителя</vendor>
                        <price_city xmlns="Опт1">5550</price_city>
                        <amount_store xmlns="Москва">2</amount_store>
                        <volume>0.25</volume>
                        <weight>7</weight>
                        <length>1116</length>
                        <height>740</height>
                        <depth>700</depth>
                        <color>Ротанг №3</color>
                        <description>текст описания</description>
                        <color_picture>53.jpg</color_picture>
                </offer>
                <offer>
                        <ID>54</ID>
                        <name>Название товара1</name>
                        <vendor>Имя производителя</vendor>
                        <price_city xmlns="Опт1">5000</price_city>
                        <amount_store xmlns="Москва">2</amount_store>
                        <volume>0.25</volume>
                        <weight>7</weight>
                        <length>1116</length>
                        <height>740</height>
                        <depth>700</depth>
                        <color>Ротанг №3</color>
                        <description>текст описания2</description>
                        <color_picture>54.jpg</color_picture>
                </offer>
        </offers>
</shop>

Как разобрать всё это в массивы
$id[]
$name[]
$price[]
 и т.д.

???

Удобный съем позиций (http://allpositions.ru/redirect/58277)
LEOnidUKG
На сайте с 25.11.2006
Offline
1730
#1

Тут на любой вкус:

https://www.google.com/

Если не хочется, тогда можно просто preg_match_all по любому элементу

Google
Google
  • www.google.com
Google использует файлы cookie и данные, чтобы: предоставлять сервисы и обеспечивать их работу, например отслеживать сбои и защищать от спама, мошенничества и других злоупотреблений; анализировать вовлеченность аудитории и статистику сайтов, чтобы узнавать, как пользуются нашими сервисами. Если вы нажмете кнопку "Принимаю", мы будем также...
✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/
X
На сайте с 04.12.2018
Offline
280
#2
 Гуглил. Те варианты, которые находил в пабликах, дают ошибку. Готовый скрипт, адаптированный под XML немного другого вида тоже, почему то, не срабатывает.
LEOnidUKG
На сайте с 25.11.2006
Offline
1730
#3
Xubart #:
 Гуглил. Те варианты, которые находил в пабликах, дают ошибку. Готовый скрипт, адаптированный под XML немного другого вида тоже, почему то, не срабатывает.

ну тогда регуляркой

preg_match_all('@<ID>(.*?)</ID>@',$xml,$ids);

print_r($ids);


lutskboy
На сайте с 22.11.2013
Offline
173
#4
$xml = simplexml_load_string($xml_string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
X
На сайте с 04.12.2018
Offline
280
#5
Всем спасибо. Задача решена.
M
На сайте с 07.05.2019
Offline
22
#6
Молодчина 
T7
На сайте с 19.09.2018
Offline
63
#7
Xubart #:
Всем спасибо. Задача решена.

Хоть и задача решена. Но, не тут

lxml.etree.XMLSyntaxError: xmlns: 'Опт1' is not a valid URI, line 8, column 49

проблема?

LEOnidUKG #:
ну тогда регуляркой

Ну так себе решение

Маленький тест

<?php

set_error_handler(function($code, $string, $file, $line){
throw new ErrorException($string, null, $code, $file, $line);
});

register_shutdown_function(function(){
$error = error_get_last();
if(null !== $error)
{
echo 'Last error: ';
print_r($error);
}
});

class tm {

private $tm = 0, $start = 0;

public function __construct( )
{
$this->start = microtime(1);
$this->tm = $this->start;
}

public function _($msg){
echo "\n----\nTrace: ", $msg, ":\n";
$t = microtime(1);

echo
" Mem,mb (usage/peak_usage): ",
sprintf('%01.2f / %01.2f', (memory_get_usage()/1048576), (memory_get_peak_usage()/1048576)),

"\n Time,ms (before start/before previous): ",
sprintf('%01.8f / %01.8f', ($t - $this->start)*1000, ($t - $this->tm)*1000 ), "\n--\n";

$this->tm = $t;
}
}

header('Content-Type:text/plain');
$tm = new tm();
$tm->_('start by phpversion ' . phpversion());

$p = '/home/www_data/old_centos_www/www/1c/public/xl.xml';

echo 'filesize, mb:', filesize($p)/1048576;


echo "\nXMLReader_\n=======\n";

$reader = new XMLReader;
$reader->open($p);
$i = 0; $j=0;
while($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT) {
if($reader->name == 'Товар') $i++;
if($reader->name == 'Группа') $j++;
}
}

$reader->close();

$tm->_( sprintf('afterXMLReader Groups/Items: %s / %s', $j, $i) );

echo "\nfile_get_contents\n=======\n";

$x = file_get_contents($p);


echo 'loadedxmlfile: ', $p, 'by size: ', strlen($x)/1048576, "MB\n";
$tm->_('afterloadxml');

try {
echo "\nSimpleXMLElement\n=======\n";

$d = new SimpleXMLElement($x);
$tm->_( sprintf( 'afterparsexml %s / %s',
count($d->{"Классификатор"}->{"Группы"}->{"Группа"}),
count($d->{"Каталог"}->{"Товары"}->{"Товар"})
));

echo "\npreg_match_all Товар\n=======\n";


preg_match_all('@(<Товар>.+</Товар>)@iusU', $x, $ids);
echo "\n!!!!!!MATCHED: ", count($ids[1]);

$tm->_( sprintf('afterpregmatch: %s matched', count($ids[1])) );

} catch (Exception $e) {
echo 'Exception: ', $e->getMessage(), "\n";
}

exit();

результат на файле 41м (10000 товаров в 92 категориях)


на этом этапе preg_match_all аут.

Тяжелый случай - 100000 товаров в 92 категориях:


414 метров в память прочитать не удалось, а XMLReader за 3 секунды все обошел.

Легкий случай


Все справились, но до preg_match_all 8 метров памяти скрипт использовал, а после 40. По времени разница 15мс, SimpleXMLElement дал лучший результат, но,  не существенно.

danforth
На сайте с 18.12.2015
Offline
153
#8
preg_matchем парсить XML максимально тупо, есть же XPath который позволяет выгребать из документа нужные свойства с любым уровнем вложенности
Junior Web Developer
LEOnidUKG
На сайте с 25.11.2006
Offline
1730
#9

Всё вижу, что 8 версия PHP.

Я же не писал, про идеальный вариант и т.д. Я говорю, что можно применить в той или иной ситуации.

Но зато не будет проблем с:

lxml.etree.XMLSyntaxError: xmlns: 'Опт1' is not a valid URI, line 8, column 49
LEOnidUKG
На сайте с 25.11.2006
Offline
1730
#10
danforth #:
preg_matchем парсить XML максимально тупо, есть же XPath который позволяет выгребать из документа нужные свойства с любым уровнем вложенности

Предельно тупо писать отсебятину, вот человек вверху всё достаточно протестировал.

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий