2013-08-20 2 views
0

Я пытаюсь найти конкретный узел в XML-файле с помощью XPath. Этот поиск работал очень хорошо под REXML, но REXML был слишком медленным для больших XML-документов. Так переехал на LibXML.xpath поиск с использованием libxml + ruby ​​

Мой простой пример обработки repomd.xml файла Yum, пример можно найти здесь: http://mirror.san.fastserv.com/pub/linux/centos/6/os/x86_64/repodata/repomd.xml

Мой тестовый сценарий выглядит следующим образом:

require 'rubygems' 
require 'libxml' 

p = LibXML::XML::Parser.file("/tmp/dr.xml") 
repomd = p.parse 

filelist = repomd.find_first("/repomd/data[@type='filelists']/[email protected]") 
puts "Length: " + filelist.length.to_s 
filelist.each do |f| 
    puts f.attributes['href'] 
end 

Я получаю эту ошибку:

Error: Invalid expression. 
/usr/lib/ruby/gems/1.8/gems/libxml-ruby-2.7.0/lib/libxml/document.rb:123:in `find': Error: Invalid expression. (LibXML::XML::Error) 
from /usr/lib/ruby/gems/1.8/gems/libxml-ruby-2.7.0/lib/libxml/document.rb:123:in `find' 
from /usr/lib/ruby/gems/1.8/gems/libxml-ruby-2.7.0/lib/libxml/document.rb:130:in `find_first' 
from /tmp/scripty.rb:6 

Я также попробовал более простые примеры, как показано ниже, но все равно не кубики.

p = LibXML::XML::Parser.file("/tmp/dr.xml") 
repomd = p.parse 
filelist = repomd.root.find(".//location") 
puts "Length: " + filelist.length.to_s 

В приведенном выше случае я получаю выход:

Length: 0 

Ваше вдохновенное руководство было бы весьма признателен, и я искал то, что я делаю неправильно, и я просто не могу понять из ...

Вот код, который будет извлечь файл и обработать его, по-прежнему не работает ...

require 'rubygems' 
require 'open-uri' 
require 'libxml' 

raw_xml = open('http://mirror.san.fastserv.com/pub/linux/centos/6/os/x86_64/repodata/repomd.xml').read 
p = LibXML::XML::Parser.string(raw_xml) 
repomd = p.parse 
filelist = repomd.find_first("//data[@type='filelists']/location[@href]") 
puts "First: " + filelist 

ответ

1

В конце концов я вернулся к REXML и использовал обработку потока. Гораздо быстрее и намного проще реализовать синтаксис XPath.

0

Посмотрите на свой код, кажется, вы хотите собрать только те элементы location, который имеет атрибут href. Если это так, то следует работать:

"//data[@type='filelists']/location[@href]" 
+0

К сожалению, никаких дальнейших предложений? Поиск возвращает «nil» – MediumDaveR

+0

@MediumDaveR попробуйте сейчас .. –

+0

по-прежнему nil :-(filelist = repomd.find_first ("// data [содержит (@ type, 'fileslists')]/location [@href]") puts "First:" + filelist.string – MediumDaveR

 Смежные вопросы

  • Нет связанных вопросов^_^