【问题标题】:Importing an XML document into a Rails database?将 XML 文档导入 Rails 数据库?
【发布时间】:2012-07-07 08:49:14
【问题描述】:

我一直在阅读一个又一个教程,但似乎没有什么对我有用。目标是获取包含元素和属性的 XML 文档,并将数据插入数据库。每个元素/属性将是数据库中的一列,每个条目是一行。这是我一直在使用的虚构 XML 文档:

<?xml version="1.0"?>
<library>
  <NAME><![CDATA[Favorite Books]]></NAME>
  <book ISBN="11342343">
    <title>To Kill A Mockingbird</title>
    <description><![CDATA[Description#1]]></description>
    <author>Harper Lee</author>
  </book>
  <book ISBN="989894781234">
    <title>Catcher in the Rye</title>
    <description><![CDATA[This is an extremely intense description.]]></description>
    <author>J. D. Salinger</author>
  </book>
  <book ISBN="123456789">
    <title>Murphy's Gambit</title>
    <description><![CDATA[Daughter finds her dad!]]></description>
    <author>Syne Mitchell</author>
  </book>
</library>

所以我想要一个包含 2 个条目的表,每个条目都有一个 ISBN、标题、描述和作者。这就是基础。 (我想 CDATA 完全是可选的。如果这是我的问题的一部分,那么我们一定要摆脱它......)

最终目标有点复杂。拥有多本书的多个图书馆。数据库之间有关系,所以我可以从我的图书数据库中引用图书馆数据库,反之亦然。我完全迷路了,绝对是一个菜鸟,但我有很好的计算机知识,并且愿意测试和尝试。

我正在使用带有默认 SQLite3 数据库 (3.6.20) 的 Rails 3.2.6。我已经安装了 REXML、ROXML、LibXML 等,并通读了 API 和演练,但一切都没有成功。必须有一种简单的方法将 XML 文档转换为带有 Book 对象(具有 .title、.author、.isbn 和 .description 方法)的 Library 对象(具有 .name 方法)。

真的很感激任何帮助!

更新!

好的,下一个问题。我一直在玩弄这背后的逻辑,并想知道执行以下操作的最佳方法...

假设我有这个经过改进的新 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>

所以现在我们有两个图书馆,第一个名为“Favorite Books”,有两本书,第二个名为“Other Books”,只有一本书。

每本书知道它属于哪个图书馆的最佳方法是什么?最初,我创建了一个图书馆数据库和一个图书数据库。每个 Book 对象都有一个 library_id 字段,它引用了正确的 Library。因此,每个数据库都可以使用“@library.books.each do |b| b.title”之类的语法正确填写。但是,这仅在我拥有一个库时才有效。

我尝试将您提供给我的 Book 循环嵌套在一个类似的 Library 循环中,但 .css 方法会找到每个匹配项,而不管它位于何处。是否有 .css 方法可以找到 UNTIL 特定点?

换句话说,我希望能够将每本书导入其各自的图书馆。我无法向 XML 文件添加任何字段。

再次感谢。

【问题讨论】:

    标签: ruby-on-rails xml sqlite


    【解决方案1】:

    我使用Nokogiri 库做了类似的事情。

    doc = Nokogiri::XML(xml_data)
    
    doc.css('book').each do |node|
      children = node.children
    
      Book.create(
        :isbn => node['ISBN'],
        :title => children.css('title').inner_text,
        :description => children.css('description').inner_text,
        :author => children.css('author').inner_text
      )
    end
    

    更新

    您可以通过以下方式创建快速测试:

    首先安装 nokogiri gem:

    gem install nokogiri
    

    然后创建一个名为 text_xml.rb 的文件,内容如下:

    require 'nokogiri'
    
    doc = Nokogiri::XML('<?xml version="1.0"?>
      <library>
        <NAME><![CDATA[Favorite Books]]></NAME>
        <book ISBN="11342343">
          <title>To Kill A Mockingbird</title>
          <description><![CDATA[Description#1]]></description>
          <author>Harper Lee</author>
        </book>
        <book ISBN="989894781234">
          <title>Catcher in the Rye</title>
          <description><![CDATA[This is an extremely intense description.]]></description>
          <author>J. D. Salinger</author>
        </book>
        <book ISBN="123456789">
          <title>Murphy\'s Gambit</title>
          <description><![CDATA[Daughter finds her dad!]]></description>
          <author>Syne Mitchell</author>
        </book>
      </library>')
    
    doc.css('book').each do |node|
      children = node.children
    
      book = {
        "isbn" => node['ISBN'], 
        "title" => children.css('title').inner_text, 
        "description" => children.css('description').inner_text, 
        "author" => children.css('author').inner_text
      }
    
      puts book
    end
    

    最后运行:

    ruby test_xml.rb
    

    我怀疑您在粘贴 xml 时没有转义 Murphy's Gambit 中的单引号。

    【讨论】:

    • 我也玩过 Nokogiri,但无济于事,但我不相信我使用过这种确切的语法。我会试一试并报告...
    • 好的,这并没有给我一个错误,所以我想我们在正确的轨道上。它没有做任何事情吗?我在 Rails 控制台中输入这个,当我输入“end”时,它只报告“0”。 doc.root 也返回“nil”,所以我认为有些事情没有按计划进行……有什么想法吗?
    • 非常感谢!我一直在尝试使用 book.title 之类的方法手动创建新书并将其插入表中。没有意识到您可以在 foreach 循环中执行 Book.create(book) 。感谢您的耐心等待,我现在独自一人!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 2015-05-03
    • 2010-10-17
    • 1970-01-01
    相关资源
    最近更新 更多