LINUX.ORG.RU

как мне лучше парсить XML?


0

0

задача такая.

Есть набор XPATH выражений. Сейчас их 10, но в будущем возможно будет несколько сотен.

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

Сейчас это делается так: из этих выражений строится XSL преобразование, которое с помощью <xsl:value-of select= извлекает их в виде текста. Далбше это текст уже по быстрому обрабатывается.

Вроде это неплохо, но на 300 килобайтном xml это преобразование занимает уже около 20 миллисек на одном ядре intel core 2 -- это для извлечения всего 8 XPATH выражений.

Хотелось бы узнать какая альтернатива может быть чтобы это ускорить?

★★★★★

А если тем же XPath вытягивать значения из xml. Либо XSLT заменить небольшой утилитой, которая будет использовать SAX

NixU
()

Вот ещё вспомнил про такую штуку как stax на http://www.xmlhack.ru была по ней вводная статья. 
Фишка в том что там не используется DOM, а следовательно скорость преобразования выше

NixU
()

Пиши свой модуль, который будет тебе это дело парсить. Используй SAX или StAX - смысл один, модели разные.

Ian ★★
()
Ответ на: комментарий от Ian

> Пиши свой модуль, который будет тебе это дело парсить. Используй SAX или StAX - смысл один, модели разные.

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

dilmah ★★★★★
() автор топика
Ответ на: комментарий от Ian

> Ну так и напиши модуль, который будет извлекать эти выражения. Я об этом.

написать компилятор xpath?

dilmah ★★★★★
() автор топика
Ответ на: комментарий от Ian

> Господи, да нет же. Я очепятался, извлекать не выражения, а значения для твоих XPath выражений.

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

dilmah ★★★★★
() автор топика
Ответ на: комментарий от Ian

А если xpath выражения изменятся, то нужно чтобы мне не нужно было переписывать никакого кода.

dilmah ★★★★★
() автор топика
Ответ на: комментарий от dilmah

Непонятна проблема. Бери любой опсорсный парсер, скармливаешь ему xpath выражения - получаешь выхлоп. 
Зачем xslt непонятно.

Тупо выдраный пример для перла:

    use XML::XPath;
    use XML::XPath::XMLParser;
    
    my $xp = XML::XPath->new(filename => 'test.xhtml');
    
    my $nodeset = $xp->find('/html/body/p'); # find all paragraphs
    
    foreach my $node ($nodeset->get_nodelist) {
        print "FOUND\n\n", 
            XML::XPath::XMLParser::as_string($node),
            "\n\n";
    }

Anoxemian ★★★★★
()
Ответ на: комментарий от Anoxemian

ну попробовал.

вытаскивались 8 больших xpath выражений.  В цикле чтобы замерить
время.  Даже на 50к xml это заняло 290 миллисек!!  С помощью xslt
то же самое занимает меньше 7 миллисек.

А на 300 кбайтном xml он мне выдал:

not well-formed (invalid token) at line 71, column 47, byte 3592:
      <item type='CDROM' id='1'>
         <attribute name='Model' value='EER245X         '/>
         <attribute name='SerialNumber' value='('/>
==============================================^
         <attribute name='FirmwareRevision' value='1.0 '/>
         <attribute name='BusType' value='SCSI'/>
 at /usr/lib/perl5/vendor_perl/5.8.8/i686-linux-thread-multi/XML/Parser.pm line 

это при том что ни xmllint, ни xsltproc, ни XML::LibXSLT на него не ругаются.

dilmah ★★★★★
() автор топика
Ответ на: комментарий от dilmah

вобщем сделал я тест с какой скоростью обрабатывает xml xmllint -- всего лишь в 2-3 раза быстрее чем у меня сейчас, так что сильно ускорить вряд ли получится..

dilmah ★★★★★
() автор топика
Ответ на: комментарий от dilmah

Надеюсь, ты сделал правильный вывод, что XML для работы с большим количеством данных непригоден?

anonymous
()
Ответ на: комментарий от NixU

Ошибся и перепутал названия имел в ввиду STX 
А вообщще немного не понятно у тебя ведь в xml лежат данные, а не XPath? Следовательно тебе нужно извлечь данные и сгенерировать по ним XPath. Я все поравильно понял? Если да то перечитай топик и найдешь ответ на все свои вопросы ;) Keywords: sax, stax, stx

NixU
()
Ответ на: комментарий от NixU

ok, посмотрю. но главного я уже достиг -- показал что я не делаю каких-то ужасно тупых вещей которые замедлили обработку на порядок:)

dilmah ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> Надеюсь, ты сделал правильный вывод, что XML для работы с большим количеством данных непригоден?

я с самого начала отстаивал позицию что формат должен быть простым набором пар ключ=значение. Технический директор сказал: xml is industrial standard..

dilmah ★★★★★
() автор топика
Ответ на: комментарий от NixU

> А вообщще немного не понятно у тебя ведь в xml лежат данные, а не XPath? Следовательно тебе нужно извлечь данные и сгенерировать по ним XPath

да, в xml данные, нужно извлечь значения xpath выражений

> Если да то перечитай топик и найдешь ответ на все свои вопросы ;) Keywords: sax, stax, stx

тут проблемка:

STX only allows queries immediately surrounding the current node

а у меня часть выражений использует count, а есть и более сложные варианты, то есть еще нужно думать уложится ли моя семантика в то что умеет делать stx..

dilmah ★★★★★
() автор топика
Ответ на: комментарий от dilmah

Видимо мы друг-друга не понимаем, или я не пойму что тебе нужно.

Тебе нужно взять Xcerces с сайта Apache - это SAX парсер. Дальше реализуешь свой ContentHandler, методы которого будут дергаться парсером при обработке XML. В методах выбираешь нужные тебе данные и сохраняешь/отправляешь/whatever. Желательно, а скорее всего обязательно, раз критична производительность, в XML делать как можно меньше объявлений namespace'ов. Если они не используются, то лучше выруби их в парсере. Тогда, чисто теоретически, будет реже дергаться определенные методы ContentHandler. Возможно выростет производительность, а может и нет... =)

Ian ★★
()
Ответ на: комментарий от Ian

> Дальше реализуешь свой ContentHandler, методы которого будут дергаться парсером при обработке XML. В методах выбираешь нужные тебе данные и сохраняешь/отправляешь/whatever.

ну это решение на крайний случай.

я танцую от имеющихся xpath выражений которые описывают, что именно мне нужно извлечь из xml. Эти xpath выражения могут в любой момент измениться или появиться новые. Вручную переделывать методы которые дергаются парсером это очень нежелательное решение. Значит должен быть компилятор который возьмет xpath выражения и преобразует их в методы которые дергает парсер. Такой компилятор готовый есть?

dilmah ★★★★★
() автор топика
Ответ на: комментарий от dilmah

> Значит должен быть компилятор который возьмет xpath выражения и преобразует их в методы которые дергает парсер. Такой компилятор готовый есть?

ИМХО, нет и быть не может =)

Ian ★★
()
Ответ на: комментарий от dilmah

Ищите. Если найдете, я с удовольствием пройду по ссылке.

Ian ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.