Обработка больших 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».

Комментарии

  1. # Бутылк.Ус

    А через парсер XML в PERL не пробовал? Там ничего сложного, мало отличается от пыха синтаксисом. Попробуй =)

  2. # Бутылк.Ус

    Чорт, я вообще туплю – есть же в факе там готовый парсер на PERL!

  3. # Тормоз

    Я, блин, так и не понял, как на этом XPath сделать выборку по условию содержимого элемента? Не атрибута, не названия, а именно содержимого. Блин, и срубаюсь спать уже, вообще голова не варит.

    Там есть <categoryId>6019</categoryId>, каким образом выбрать все элементы, внутри которых categoryId 6019? Такое ощущение, будто вообще никак… а это очень плохо.

  4. # Тормоз

    Ага, вроде string() для этого предназначен. Блин, кто выдумывал синтаксис такой? Ладно, запускаю тестовый обработчик и спать уже. А то не помню когда последний раз спал :)

  5. # oddm: 

    Тормоз: кажись //categoryId[text()=6019]

  6. # макс: 

    юзай python или node.js они раз в 10 быстрее чем пхп работают, плюс есть уже готовые решения. у меня распарсить 500 мб xml в массив и запихнуть все в базу mysql через цыкл в node.js занимант меньше 30 секунд на vds c 512мб памяти.

  7. # Тормоз

    Мда, что-то нихрена не работает с этим string(), блин.

    Макс, а что конкретно на Пайтоне ты используешь для этого?

  8. # Тормоз

    То ли я дурак, то ли всё через жопу как обычно. XML_split попробовал, чтобы потом из PHP всё ж поработать над меньшими кусочками, поставил опцию -s 10M, а оно books-01.xml уже за 50 Мб сделало и продолжает туда писать. Злит.

  9. # Тормоз

    Ничччего не понимаю. Сколько размер ни ставь, он всё равно пишет в один файл, хоть ты тресни. Но создаёт два (00 и 01, в который и пишет). Что к чему?

  10. # макс: 

    habrahabr.ru/blogs/p…
    habrahabr.ru/blogs/p…
    habrahabr.ru/blogs/p…

    решений на самом деле много разных, на хабре много статей на тему попробуй поискать по ключам «xml php» или «xml python»
    если надо импортировать напрямую в бузу данных, то в mysql есть подобная возможность импорта из xml что на несколько тыячь процентов быстрее чем с использованием языка програмирования для парсинга

  11. # Георгий: 

    Ухтыы) наконец Тормоз принялся за что-то помимо Даоса. Мож намекнешь хотяб что за идея и чего нам ждать?

  12. # DimaX

    У них в факе валяется готовый хмл парсер на пхп5, у меня на одном сайте он работает уже 2 года без проблем. Зачем велосипед-то изобретать.

  13. # Karden: 

    В PHP можно воспользоваться, например, XMLReader

    Он очень быстрый, и отлично подходит для больших файлов (читает в потоке, не пытаясь загрузить файл целиком).

  14. # Тормоз

    Всем спасибо! Попробую один из указанных вами инструментов.

  15. # nugops: 

    Тормоз, тебе нужен потоковый обработчик xml – SAX (Simple API for XML). Он не стоит DOM дерево, следовательно не требует много памяти и быстро работает. Его реализация есть на любом языке: python, perl уверен и на php тоже есть.

  16. # Тормоз

    Ага, я уж читал про SAX вчера, но что-то подумал, что специальные консольные утилитки (которые тем способом и сделаны наверняка) будут лучше. А вот не справились чего-то. Всем спасибо. Разберусь скоро.

  17. # kp: 

    С такими большими xml не сталкивался, но файл на 60 метров без натугов разбирается через xml_parser_create за несколько минут. Как уже сказали выше, на сайте php есть пример.

  18. # Безумный Программист

    Perl пропарсил бы ваш XML за минуты. Он, собственно, для таких задач и создавался.

  19. # Pamparam: 

    а если я не разбираюсь во всех этих пёрлах?
    … интересно, может вот это подойдет: sypex.net/ ?

  20. # Безумный Программист

    Я не хочу строить коллайдер. Мне просто нужно поразгонять частицы

    (с) баш

  21. # Sterx: 

    phpQuery рекомендуе

Комментирование этой статьи закрыто.

Интересное Покупки ТехникаРазное Отдых Статьи Строительство Услуги Общество Хобби Культура Советы Уют