说我有以下XML文档。我使用Ruby 1.9.3,Rails 3.2.6和Nokogiri 1.5.5将XML解析为数据库。我希望能够遍历XML标记并以正确的顺序挑选元素。
<?xml version="1.0"?>
<RandomTag>
<library name='Favorite Books'>
<book ISBN="11342343">
<title>TKAM</title>
<description>Desc1</description>
<author>H Lee</author>
</book>
<book ISBN="989894781234">
<title>Catcher in the Rye</title>
<description>Desc2</description>
<author>JD S</author>
</book>
</library>
<library name='Other Books'>
<book ISBN="123456789">
<title>Murphy\'s Gambit</title>
<description>Desc3</description>
<author>Syne M</author>
</book>
</library>
</RandomTag>
我正在使用类似于以下内容的循环来迭代:
f = File.open(args[:file])
doc = Nokogiri::XML(f)
f.close
doc.css('library').each do |node|
children = node.children
lib = {"name" => node['name']}
Library.create(lib)
doc.css('book').each do |n|
churn = n.children
book = {#book elements}
Book.create(book)
end
end
所以我基本上都在寻找一个图书馆,然后一旦找到它,我就会搜索该图书馆里的所有图书。我当前代码的问题是.css()方法搜索到EOF。因此内部的“书”循环会影响每一本书,无论它位于哪个库中。另外,一旦我点击了第二个库,“书籍”循环将再次从文档的开头开始,并继续贯穿每本书。最终结果是我得到了正确数量的具有正确名称的库,但每个库都有每本书。当我点击一个新的“图书馆”标签时,我需要一种方法来停止搜索书籍(从内循环中断)。
是否有与.css()不同的方法来执行此操作?有没有办法在我的循环中写一个break语句来退出给定的情况?
答案 0 :(得分:2)
你找到了所有的书,因为你正在打电话
doc.css('book')
根据定义,搜索文档中的任何书籍。如果您只想在某个元素中查找图书,请拨打.css
:
doc.css('library').each do |library_node|
library_node.css('book').each do |book_node|
#only iterates on the books inside that library
end
end
答案 1 :(得分:1)
你在这里看到的是一个迭代器。该方法迭代它找到的所有属性。
如果nokogiri支持可枚举模块,您可以使用其他几种方法:
http://apidock.com/ruby/Enumerable
在您的情况下,您将使用find来使用第一个匹配元素。