如何使用Nokogiri从哈希中构建节点

问题描述 投票:1回答:2

[许多人通常想做相反的转换,但是我想从Ruby哈希(具有许多嵌套的哈希,甚至是数组)中构建一个节点:

my_hash = {
  "name" => "Something",
  "property_1" => "Something"
  "nested_array_items" => [{ "name" => "Nasty nested array item", 
                  "advice" => "Use recursive function" },
                 { "name" => "yes this is an array",
                  "notice" => "not necessarily the same keys"}],
  "nested_many_levels" => { "additional_items" => { "ok_stop_here" => true } },
}

我有一个Nokogiri节点,应包含所有这些内容。如何定义要执行的功能?

每个子节点都应该用键名来命名,最终用“ _”替换“ -”。对于数组,假设项为正则复数(以“ s”结尾,否则会引起错误),请为每个项使用键名称的单数。

例如,上面给出的哈希应变为:

...
<name>something></name>
<property_1>Something</property_1>
<nested_array_items>
  <nested_array_item>
    <name>Nasty nested array item</name>
    <advice>Use recursive function</advice>
  </nested_array_item>
  <nested_array_item>
    <name>yes this is an array</name>
    <notice>not necessarily the same keys</notice>
  </nested_array_item>
</nested_array_items>
<nested_many_levels>
  <additional_items>
      <ok_stop_here>true</ok_stop_here>
  </additional_items>
</nested_many_levels>
...

许多人通常想做相反的转换,但是我想从Ruby哈希(具有许多嵌套的哈希,甚至是数组)构建一个节点:my_hash = {“ name” =>“ Something”,“ ...] >

ruby xml recursion hash nokogiri
2个回答
1
投票

好的,我意识到从哈希构建节点不是我的最佳选择(就我而言,我希望具有完整的XML结构,即使某些节点由于缺少哈希内容而为空)。

因此,我正在使用一个XML模板节点,该节点已经包含我想要的完整结构,并且只有长度为1的数组。因此,为了构建新节点,我将现有的节点复制了我需要的次数(预处理) ,然后替换内容。


-2
投票

好的,这是我的代码,似乎可以正常工作!

def  build_node_recursively(node, content_hash, xml_document)
    content_hash.each do |key, val|
        new_node = Nokogiri::XML::Node.new "#{key.to_s}", xml_document
        # Val can be : a value | an array of hashes | another hash
        if val.is_a?(Array)
            item_label = key.to_s.singularize
            val.each do |item|  # Assume item is another content_hash. Wouldn't make sense (for me) to have just a value...
                item_node = Nokogiri::XML::Node.new item_label, xml_document
                new_node << build_node_recursively(item_node, item)
            end
        elsif val.is_a?(Hash)
            build_node_recursively(new_node, val)
        else
            new_node.content = val.to_s
        end
        node << new_node
    end
end
© www.soinside.com 2019 - 2024. All rights reserved.