2009-02-20 102 views
2

使用XPath可以使用什么Ruby库来选择属性,并将其用作其他XPath查询的起点。Ruby XPath查找属性

实施例:

<root> 
    <add key="A" value="B" /> 
    <add key="C" value="D" /> 
    <add foo="E" bar="F" /> 
</root> 

希望的代码:

get_pair "//*/@key", "../@value" 
get_pair "//*/@foo", "../@bar" 

预期输出:

"A" "B" 
"C" "D" 
"E" "F" 

伪实现:

def get_pair(key, value) 
    xml_doc.select[key].each do |a| 
    puts [a, a.select[value]] 
    end 
end 

回答

4

你的起点是REXML

“挑战”在这里是如何看待的属性节点作为子节点,而这可以通过使用singleton methods来完成,那么一切遵循自然:

require "rexml/document" 
include REXML # so that we don't have to prefix everything with REXML::... 

def get_pair(xml_doc, key, value) 
    XPath.each(xml_doc, key) do |node| 
    if node.is_a?(Attribute) 
     def node.parent 
     self.element 
     end 
    end 
    puts "\"#{node}\" \"#{XPath.first(node, value)}\"" 
    end 
end 

xml_doc = Document.new <<EOF 
    <root> 
    <add key="A" value="B" /> 
    <add key="C" value="D" /> 
    <add foo="E" bar="F" /> 
    </root> 
EOF 

get_pair xml_doc, "//*/@key", "../@value" 
get_pair xml_doc, "//*/@foo", "../@bar" 

生产:

"A" "B" 
"C" "D" 
"E" "F" 
0

我也建议寻找角度来说,Hpricot ......这是一个非常富有表现力的HTML和XML解析库,的jQuery的启发。

1

如果您将在性能问题的任何区域解析体面的数据量,那么您将需要libxml-ruby。 REXML和Hpricot都很好,但是最近我不得不在自己的服务器上进行一些解析工作,因为它的速度提高了大约1200%。

0

REXML,附带了红宝石会做你想要什么:

require 'rexml/document' 
include REXML 
xml = Document.new('<root><add key="A" value="B" /><add key="C" value="D" /><add foo="E" bar="F" /></root>') 
xml.root.each_element_with_attribute('key'){|e| puts "#{e.attribute('key')} #{e.attribute('value')}"} 
3

显然引入nokogiri是最快的Ruby的XML解析器

http://www.rubyinside.com/nokogiri-ruby-html-parser-and-xml-parser-1288.html

今天使用它,它的伟大。

对于示例:

doc = Nokogiri::XML(your_xml) 
doc.xpath("/root/add").map do |add| 
    puts [add['key'], add['value']] 
end 

编辑:这并不奇怪原来outthat声称引入nokogiri快不无争议。

然而,我们发现它比我们的生产environmenty libxml的更稳定(libxml的偶尔崩溃,只是在引入nokogiri交换已经解决了这个问题)

+0

它描述为“比的libxml-红宝石略慢”的HTTP ://tenderlovemaking.com/2008/10/30/nokogiri-is-released/评论部分。 – 2009-02-23 02:05:55