2012-08-13 12 views
6

मैं की तरह नेस्टेड हैश के कई स्तरों है: मैं xml.send की कोशिश की है इस ?: तरहका उपयोग कर एक्सएमएल में नेस्टेड हैश परिवर्तित nokogiri

<foo>bar</foo> 
<foo1> 
    <foo2>bar2</foo2> 
    <foo3>bar3</foo3> 
    <foo4> 
     <foo5>bar5</foo5> 
    </foo4> 
</foo1> 

{ :foo => 'bar', :foo1 => { :foo2 => 'bar2', :foo3 => 'bar3', :foo4 => { :foo5 => 'bar5' }}} 

कैसे मैं उन्हें एक एक्सएमएल में बदल सकते हैं विधि, लेकिन यह उपरोक्त नेस्टेड हैश को परिवर्तित करता है:

<foo1 foo3="bar3" foo4="foo5bar5" foo2="bar2"/> 
<foo>bar</foo> 
+0

रेल में आप बस hash.to_xml सकता है – ecoologic

+0

धन्यवाद ecologic, लेकिन मैं उन्हें enclosing टैग है .. मैं उन्हें नहीं चाहते। स्ट्रिंग मैनिप्लेशंस के बजाय उन्हें उत्पन्न करने का कोई सीधा आगे तरीका है ?? – Hari

उत्तर

8

इसके बारे में कैसे?

class Hash 
  def to_xml 
    map do |k, v| 
      text = Hash === v ? v.to_xml : v 
      "<%s>%s</%s>" % [k, text, k] 
    end.join 
  end 
end 

h.to_xml 
#=> "<foo>bar</foo><foo1><foo2>bar2</foo2><foo3>bar3</foo3><foo4><foo5>bar5</foo5></foo4></foo1>" 
+0

बहुत बढ़िया कोडिंग। धन्यवाद :) – Hari

+0

क्या आप बता सकते हैं कि नक्शा और end.join क्या करते हैं ??? – Hari

+1

बहुत ही सुरुचिपूर्ण समाधान। –

3

स्वीकार किए जाते हैं एक साफ समाधान है, लेकिन नीचे वास्तव में 'उपयोग' Nokogiri एक्सएमएल एक हैश से विशेषताओं के लिए विशेष हैंडलिंग के साथ निर्माण करने के लिए करता है:

require 'nokogiri' 

def generate_xml(data, parent = false, opt = {}) 
    return if data.to_s.empty? 
    return unless data.is_a?(Hash) 

    unless parent 
     # assume that if the hash has a single key that it should be the root 
     root, data = (data.length == 1) ? data.shift : ["root", data] 
     builder = Nokogiri::XML::Builder.new(opt) do |xml| 
      xml.send(root) { 
       generate_xml(data, xml) 
      } 
     end 

     return builder.to_xml 
    end 

    data.each { |label, value| 
     if value.is_a?(Hash) 
      attrs = value.fetch('@attributes', {}) 
      # also passing 'text' as a key makes nokogiri do the same thing 
      text = value.fetch('@text', '') 
      parent.send(label, attrs, text) { 
       value.delete('@attributes') 
       value.delete('@text') 
       generate_xml(value, parent) 
      } 

     elsif value.is_a?(Array) 
      value.each { |el| 
       # lets trick the above into firing so we do not need to rewrite the checks 
       el = {label => el} 
       generate_xml(el, parent) 
      } 

     else 
      parent.send(label, value) 
     end 
    } 
end 

puts generate_xml(
    {'myroot' => 
     { 
      'num' => 99, 
      'title' => 'something witty', 
      'nested' => { 'total' => [99, 98], '@attributes' => {'foo' => 'bar', 'hello' => 'world'}}, 
      'anothernest' => { 
       '@attributes' => {'foo' => 'bar', 'hello' => 'world'}, 
       'date' => [ 
        'today', 
        {'day' => 23, 'month' => 'Dec', 'year' => {'y' => 1999, 'c' => 21}, '@attributes' => {'foo' => 'blhjkldsaf'}} 
       ] 
      } 
    }}) 
puts puts 
puts generate_xml({ 
      'num' => 99, 
      'title' => 'something witty', 
      'nested' => { 'total' => [99, 98], '@attributes' => {'foo' => 'bar', 'hello' => 'world'}}, 
      'anothernest' => { 
       '@attributes' => {'foo' => 'bar', 'hello' => 'world'}, 
       'date' => [ 
        'today', 
        {'day' => [23,24], 'month' => 'Dec', 'year' => {'y' => 1999, 'c' => 21}, '@attributes' => {'foo' => 'blhjkldsaf'}} 
       ] 
      } 
    }) 

और जिसके परिणामस्वरूप XML आउटपुट:

<?xml version="1.0"?> 
<myroot> 
    <num>99</num> 
    <title>something witty</title> 
    <nested foo="bar" hello="world"> 
    <total>99</total> 
    <total>98</total> 
    </nested> 
    <anothernest foo="bar" hello="world"> 
    <date>today</date> 
    <date foo="blhjkldsaf"> 
     <day>23</day> 
     <month>Dec</month> 
     <year> 
     <y>1999</y> 
     <c>21</c> 
     </year> 
    </date> 
    </anothernest> 
</myroot> 


<?xml version="1.0"?> 
<root> 
    <num>99</num> 
    <title>something witty</title> 
    <nested foo="bar" hello="world"> 
    <total>99</total> 
    <total>98</total> 
    </nested> 
    <anothernest foo="bar" hello="world"> 
    <date>today</date> 
    <date foo="blhjkldsaf"> 
     <day>23</day> 
     <day>24</day> 
     <month>Dec</month> 
     <year> 
     <y>1999</y> 
     <c>21</c> 
     </year> 
    </date> 
    </anothernest> 
</root> 
संबंधित मुद्दे