Обработка больших XML-файлов
28.04.2011 технологии изучение Линукса
Для одного проектика стянул с партнёрки My-Shop.ru огромный XML (более 230 Мб, все товары) и сперва по наивности своей попробовал через PHP его обработать. Ха! Фигушки.
Пришлось искать решения. В принципе, с помощью grep получалось кое-что, но всё ж удобней специальные инструменты. И они есть такие, одно из них XML_grep называется. В Debian можно найти через репозитории, пакет называется xml-twig-tools. Заодно пришлось разбираться в XPath. Ну и заморочки! Столько всяких премудростей, мозголомка настоящая.
Самое смешное будет, если идею, ради которой вся эта волокита, реализовать не получится на должном уровне. Такое вполне может быть, на это раз я замахнулся на серьезную такую задачку.
P.S. XMLstarlet не заработал почему-то, ошибки всякие.
P.P.S. Пока писал заметку, было обработано более 60 Мб.
Но ещё не всё, это лишь начало.
xml_grep "//offer[@type='book']" db_win-1251.xml > books.xml
Вам необходимо выполнить работы электроинструментами там, где электричества нет? У этой проблемы есть решение – дизель генератор. А купить его вы сможете, не выходя из дома, благодаря интернет магазину «In-Green».
Комментарии
Комментирование этой статьи закрыто.
« О верстальщиках Логинзы, а также немного про FireFox и Vimperator Эх, молодёжь »
А через парсер XML в PERL не пробовал? Там ничего сложного, мало отличается от пыха синтаксисом. Попробуй =)
Чорт, я вообще туплю – есть же в факе там готовый парсер на PERL!
Я, блин, так и не понял, как на этом XPath сделать выборку по условию содержимого элемента? Не атрибута, не названия, а именно содержимого. Блин, и срубаюсь спать уже, вообще голова не варит.
Там есть <categoryId>6019</categoryId>, каким образом выбрать все элементы, внутри которых categoryId 6019? Такое ощущение, будто вообще никак… а это очень плохо.
Ага, вроде string() для этого предназначен. Блин, кто выдумывал синтаксис такой? Ладно, запускаю тестовый обработчик и спать уже. А то не помню когда последний раз спал :)
Тормоз: кажись //categoryId[text()=6019]
юзай python или node.js они раз в 10 быстрее чем пхп работают, плюс есть уже готовые решения. у меня распарсить 500 мб xml в массив и запихнуть все в базу mysql через цыкл в node.js занимант меньше 30 секунд на vds c 512мб памяти.
Мда, что-то нихрена не работает с этим string(), блин.
Макс, а что конкретно на Пайтоне ты используешь для этого?
То ли я дурак, то ли всё через жопу как обычно. XML_split попробовал, чтобы потом из PHP всё ж поработать над меньшими кусочками, поставил опцию -s 10M, а оно books-01.xml уже за 50 Мб сделало и продолжает туда писать. Злит.
Ничччего не понимаю. Сколько размер ни ставь, он всё равно пишет в один файл, хоть ты тресни. Но создаёт два (00 и 01, в который и пишет). Что к чему?
habrahabr.ru/blogs/p…
habrahabr.ru/blogs/p…
habrahabr.ru/blogs/p…
решений на самом деле много разных, на хабре много статей на тему попробуй поискать по ключам «xml php» или «xml python»
если надо импортировать напрямую в бузу данных, то в mysql есть подобная возможность импорта из xml что на несколько тыячь процентов быстрее чем с использованием языка програмирования для парсинга
Ухтыы) наконец Тормоз принялся за что-то помимо Даоса. Мож намекнешь хотяб что за идея и чего нам ждать?
У них в факе валяется готовый хмл парсер на пхп5, у меня на одном сайте он работает уже 2 года без проблем. Зачем велосипед-то изобретать.
В PHP можно воспользоваться, например, XMLReader
Он очень быстрый, и отлично подходит для больших файлов (читает в потоке, не пытаясь загрузить файл целиком).
Всем спасибо! Попробую один из указанных вами инструментов.
Тормоз, тебе нужен потоковый обработчик xml – SAX (Simple API for XML). Он не стоит DOM дерево, следовательно не требует много памяти и быстро работает. Его реализация есть на любом языке: python, perl уверен и на php тоже есть.
Ага, я уж читал про SAX вчера, но что-то подумал, что специальные консольные утилитки (которые тем способом и сделаны наверняка) будут лучше. А вот не справились чего-то. Всем спасибо. Разберусь скоро.
С такими большими xml не сталкивался, но файл на 60 метров без натугов разбирается через xml_parser_create за несколько минут. Как уже сказали выше, на сайте php есть пример.
Perl пропарсил бы ваш XML за минуты. Он, собственно, для таких задач и создавался.
а если я не разбираюсь во всех этих пёрлах?
… интересно, может вот это подойдет: sypex.net/ ?
Я не хочу строить коллайдер. Мне просто нужно поразгонять частицы
(с) баш
phpQuery рекомендуе