【问题标题】:Using Ruby loops to parse an XML doc使用 Ruby 循环解析 XML 文档
【发布时间】:2012-07-11 15:18:49
【问题描述】:

假设我有以下 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 语句以在给定情况下退出?

【问题讨论】:

    标签: ruby-on-rails ruby xml loops


    【解决方案1】:

    你找到所有的书是因为你在打电话

    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
    

    【讨论】:

    • 当然。可能应该自己想出来一个哈哈...谢谢!
    【解决方案2】:

    你在这里看到的是一个迭代器。该方法遍历它找到的所有属性。

    如果 nokogiri 支持 enumerable 模块,您可以使用其他几种方法:

    http://apidock.com/ruby/Enumerable

    在您的情况下,您将使用 find 来仅使用第一个匹配元素。

    【讨论】:

    • 好的,所以我使用 .find 搜索第一个库。现在我有了。现在我需要遍历(枚举?)所有书籍,直到我点击下一个图书馆标签。我再次使用 .find 来获取第一本书。我将这个 .find 方法放在一个循环中以查找所有书籍。如何停止查找书籍并继续查找图书馆?
    猜你喜欢
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 2021-05-03
    • 2015-03-23
    • 1970-01-01
    • 2015-12-10
    相关资源
    最近更新 更多