使用'ox'gem

时间:2017-12-20 11:10:37

标签: ruby xml

我目前正在尝试使用ox gem创建一个xml文档中的哈希值

输入xml:

<?xml version="1.0"?>
<expense>
  <payee>starbucks</payee>
  <amount>5.75</amount>
  <date>2017-06-10</date>
</expense> 

使用以下ruby / ox代码:

doc = Ox.parse(xml)
plist = doc.root.nodes

我得到以下输出:

=> [#<Ox::Element:0x00007f80d985a668 @value="payee", @attributes={}, @nodes=["starbucks"]>, #<Ox::Element:0x00007f80d9839198 @value="amount", @attributes={}, @nodes=["5.75"]>, #<Ox::Element:0x00007f80d9028788 @value="date", @attributes={}, @nodes=["2017-06-10"]>]

我想要的输出是格式为的哈希:

{'payee'  => 'Starbucks',
'amount' => 5.75,
'date'   => '2017-06-10'}

保存在我的sqllite数据库中。
如何将对象数组转换为如上所述的哈希值。
任何帮助都非常感谢。

2 个答案:

答案 0 :(得分:1)

文档建议您使用以下内容:

require 'ox'

xml = %{
<top name="sample">
  <middle name="second">
    <bottom name="third">Rock bottom</bottom>
  </middle>
</top>
}

puts Ox.load(xml, mode: :hash)
puts Ox.load(xml, mode: :hash_no_attrs)

#{:top=>[{:name=>"sample"}, {:middle=>[{:name=>"second"}, {:bottom=>[{:name=>"third"}, "Rock bottom"]}]}]}
#{:top=>{:middle=>{:bottom=>"Rock bottom"}}}

我不确定这正是你正在寻找的东西。

否则,它实际上取决于数组中Ox::Element个实例的可用方法。

the docs开始,此处有两种方便的方法:您可以使用[]text

因此,我使用reduce将数组强制转换为您正在寻找的哈希格式,使用如下内容:

ox_nodes = [#<Ox::Element:0x00007f80d985a668 @value="payee", @attributes={}, @nodes=["starbucks"]>, #<Ox::Element:0x00007f80d9839198 @value="amount", @attributes={}, @nodes=["5.75"]>, #<Ox::Element:0x00007f80d9028788 @value="date", @attributes={}, @nodes=["2017-06-10"]>]

ox_nodes.reduce({}) do |hash, node|
  hash[node['@value']] = node.text
  hash
end

我不确定node['@value']是否有效,所以您可能需要对此进行试验 - 否则node.instance_variable_get('@value')可能会这样做。

node.text执行以下操作,听起来是正确的:

  

返回元素nodes数组中的第一个String,如果没有String节点,则返回nil。

N.B。我更喜欢使用reduce稍微整理tap块,如下所示:

ox_nodes.reduce({}) do |hash, node|
  hash.tap { |h| h[node['@value']] = node.text } 
end

希望有所帮助 - 让我知道你是如何上场的!

答案 1 :(得分:1)

我在上一篇评论中找到了问题的答案:

def create_xml(expense)
    Ox.default_options=({:with_xml => false})
    doc = Ox::Document.new(:version => '1.0')
    expense.each do |key, value|
        e = Ox::Element.new(key)
        e << value
        doc << e
    end
    Ox.dump(doc)
end

接下来的问题是如何将金额密钥的值从字符串转换为整数befopre将其保存到数据库