使用libxml + ruby​​进行xpath搜索

时间:2013-08-20 09:58:41

标签: ruby xpath libxml2 libxml-ruby

我正在尝试使用XPath在XML文件中搜索特定节点。这种搜索在REXML下工作得很好,但REXML对于大型XML文档来说太慢了。所以转移到LibXML

我的简单示例是处理Yum repomd.xml文件,可在此处找到示例: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']/location@href")
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

2 个答案:

答案 0 :(得分:1)

最后,我又回到了REXML并使用了流处理。更快,更容易的XPath语法实现。

答案 1 :(得分:0)

查看代码,您似乎只想收集具有location属性的href个元素。如果是这种情况应该起作用:

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