2013-03-19 3 views
0

Я получаю данные от веб-службы, 100 <row> на страницу. Мой скрипт соединяет эти страницы с Nokogiri :: XML :: Nodeset. Поиск набора узлов через XPath чрезвычайно медленный.Производительность XPath с объединенным Nokogiri :: XML :: NodeSets?

Этот код заменяет службы вызова веб и XML синтаксический, но этот симптом является тот же:

rows = [] 
(1..500).to_a.each_slice(100) { |slice| 
    rows << Nokogiri::XML::Builder.new { |xml| 
    xml.root { 
     xml.rows { 
     slice.each { |num| 
      xml.row { 
      xml.NUMBER { 
       xml.text num 
      } 
      } 
     } 
     } 
    } 
    }.doc.at('/root/rows') 
} 

rows = rows.map { |a| a.children }.inject(:+) 

В результате NodeSet содержит узлы из пяти документов. Это, как представляется, проблема:

rows.map { |r| r.document.object_id }.uniq 
    => [21430080, 21732480, 21901100, 38743080, 40472240] 

Проблема: Следующий код работает примерно десять секунд. С не-объединенном множества узлов это делается в мгновение ока:

(1..500).to_a.sample(100).each do |sample| 
    rows.at('//row[./NUMBER="%d"]' % sample) 
end 

ли кто-нибудь есть решение объединить Nodesets лучший способ или объединить документы?

Я хотел бы сохранить поведение только один набор узлов, поскольку эти данные практически один большой набор узлов, который был разделен на веб-сервиса по техническим причинам.

+1

Почему вы пытаетесь собрать набор узлов? Почему бы просто не собрать нужные данные? –

+0

Часть сбора данных и сборка выполняется с помощью интерфейса интерфейса webservice (строитель должен продемонстрировать поведение). Этот метод возвращает NodeSet. Код xpath выполняется кодом, который использует этот класс. Было бы неплохо, если бы мне не пришлось менять интерфейс методов класса. – krissi

+0

Nokogiri работает очень быстро и построена на базе XML-анализатора. Вы не приводите пример XML-анализа, который вы обрабатываете, или добавляемые вместе узлы NodeSets, и, как мне кажется, попытка сравнить скорость синтаксического анализа или построения не очень важен - вы сравниваете яблоки с апельсины. Как есть, ваш вопрос не имеет для меня большого смысла. –

ответ

0

Ключ для объединения Nodesets является отсоединять узлы с узлом # удалять и добавлять их в другой набор узлов:

nodeset = nil 
rows.each do |slice| 
    if nodeset.nil? 
    nodeset = slice 
    else 
    slice.children.each do |row| 
     nodeset.add_child(row.remove) 
    end 
    end 
end 
Смежные вопросы