拥有如下所示的Ruby REXML元素:
<a_1>
<Tests>
<test enabled='1'>trans </test>
<test enabled='1'>ac </test>
<test enabled='1'>dc </test>
</Tests>
<Corners>
<corner enabled='0'>default</corner>
<corner enabled='1'>C0 </corner>
</Corners>
</a_1>
我想找到所有叶元素,因此结果应为:
<test enabled='1'>trans </test>
<test enabled='1'>ac </test>
<test enabled='1'>dc </test>
<corner enabled='0'>default</corner>
<corner enabled='1'>C0 </corner>
我的代码是:
require 'rexml/document'
include REXML
def getAllLeaf(xmlElement)
if xmlElement.has_elements?
xmlElement.elements.each {|e|
getAllLeaf(e)
}
else
return xmlElement
end
end
它工作正常,并在屏幕上显示正确的输出。但是,当我尝试将结果保存到数组时,我发现我遇到了一个问题,这个递归过程。所以如果有一种方法可以将这个输出保存到一个可以在以后使用的数组,那么我是否更有意思?
我努力以递归的方式做到这一点,虽然有点奇怪,我想分享一下:
def getAllLeaf(eTop,aTemp=Element.new("LeafElements"))
if eTop.has_elements?
eTop.elements.each {|e|
getAllLeaf(e,aTemp)
}
else
aTemp<< eTop.dup
end
return aTemp
end
答案 0 :(得分:0)
它工作正常,并在屏幕上显示正确的输出。
实际上,代码在任何地方都没有输出。在任何情况下,您的递归函数都不起作用,当Tests>
看起来像这样时,如果您在元素&lt; <Tests>
上调用方法,则可以看到:
<Tests>
<test enabled='1'>
<HELLO>world</HELLO>
</test>
<test enabled='1'>ac </test>
<test enabled='1'>dc </test>
</Tests>
你的递归方法不起作用,因为当你写:
xmlElement.elements.each {|e|
each()方法返回左边的东西,即xmlElement.elements。给定xml,递归方法等同于:
def getAllLeaf(xmlElement)
xmlElement.elements.each {|e|
"blah" #your code here has no effect on what each() returns.
}
end
..相当于:
def getAllLeaf(xmlElement)
return xmlElement.elements
end
你想坚持递归吗?搜索没有子元素的元素的所有元素要简单得多:
require "rexml/document"
include REXML
xml = <<'END_OF_XML'
<a_1>
<Tests>
<test enabled='1'>trans </test>
<test enabled='1'>ac </test>
<test enabled='1'>dc </test>
</Tests>
<Corners>
<corner enabled='0'>default</corner>
<corner enabled='1'>C0 </corner>
</Corners>
</a_1>
END_OF_XML
doc = Document.new xml
root = doc.root
XPath.each(root, "//*") do |element|
if not element.has_elements?
enabled = element.attributes['enabled']
text = element.text
puts "#{enabled} ... #{text}"
end
end
--output:--
1 ... trans
1 ... ac
1 ... dc
0 ... default
1 ... C0
或者,如果所有叶元素都是具有属性&#34;启用&#34;的唯一元素,则应执行此操作:
XPath.each(root, "//*[@enabled]") do |element|
enabled = element.attributes['enabled']
text = element.text
puts "#{enabled} ... #{text}"
end
甚至还有一个神秘的xpath会直接选择没有元素子元素的元素:
XPath.each(root, "//*[not(*)]") do |element|
enabled = element.attributes['enabled']
text = element.text
puts "#{enabled} ... #{text}"
end
另外,您是否考虑过使用nokogiri宝石?它几乎是ruby的标准XML / HTML解析器。