# Is it possible to create a hash dynamically?

**URL:** <https://www.ruby-forum.com/t/is-it-possible-to-create-a-hash-dynamically/141803>\
**Category:** Ruby\
**Created:** [June 30, 2008, 6:35pm UTC](https://www.ruby-forum.com/t/is-it-possible-to-create-a-hash-dynamically/141803 "2008-06-30T18:35:56Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![aidy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/eada6e/32.png) [@aidy](https://www.ruby-forum.com/u/aidy)\
**Post date:** [June 30, 2008, 6:35pm UTC](https://www.ruby-forum.com/t/is-it-possible-to-create-a-hash-dynamically/141803/1 "2008-06-30T18:35:56Z")

</div>

Hi,

I am trying to build a dynamic hash map

`
  def extract(xml, path)
      require 'rexml/document'
      xml = xml.to_s.gsub("utf-16", "utf-8")
      doc = REXML::Document.new(xml)
      doc.root.each_element(path) do |element|
          element.each_element do |node|
          puts "name: #{node.name} text: #{node.text}"
          @xml_data = {node.name => node.text}
        end
      end
      return @xml_data
    end
`

However, the @xml\_data is always returning 1 element

Thanks

Aidy

---

<div class="post-metadata">

**Author:** ![aidy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/eada6e/32.png) [@aidy](https://www.ruby-forum.com/u/aidy)\
**Post date:** [June 30, 2008, 6:50pm UTC](https://www.ruby-forum.com/t/is-it-possible-to-create-a-hash-dynamically/141803/2 "2008-06-30T18:50:00Z")

</div>

On Monday 30 June 2008, aidy wrote:

> ```
> element.each_element do |node|
> 
> ```
> 
> Thanks
> 
> Aidy

The problem is in the line

@xml\_data = {node.name =\> node.text}

At each iteration, you discard the old content of the variable and  
replace it  
with a new hash. This way, at the end of the cycle, the @xml\_data will  
be a  
hash containing only the text of the last node.

To do what you want, you should set @xml\_data to an empty hash outside  
the  
outer each, then store the new node in the hash at each iteration:

def extract(xml, path)  
require ‘rexml/document’  
xml = xml.to\_s.gsub(“utf-16”, “utf-8”)  
doc = REXML::Document.new(xml)  
@xml\_data = {}  
doc.root.each\_element(path) do |element|  
element.each\_element do |node|  
puts “name: #{node.name} text: #{node.text}”  
@xml\_data[node.name] =\> node.text}  
end  
end  
return @xml\_data  
end

By the way, are you sure @xml\_data needs to be an instance variable?  
From the  
way you use it in the piece of code you posted, it seems it should be a  
local  
variable.

I hope this helps

Stefano

---

<div class="post-metadata">

**Author:** ![aidy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/eada6e/32.png) [@aidy](https://www.ruby-forum.com/u/aidy)\
**Post date:** [June 30, 2008, 6:51pm UTC](https://www.ruby-forum.com/t/is-it-possible-to-create-a-hash-dynamically/141803/3 "2008-06-30T18:51:46Z")

</div>

On Mon, Jun 30, 2008 at 12:32 PM, aidy [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> ```
> element.each_element do |node|
> puts "name: #{node.name} text: #{node.text}"
> @xml_data = {node.name => node.text}
> end
> end
> return @xml_data
> 
> ```
> 
> end
> 
> However, the @xml\_data is always returning 1 element

def extract(xml, path)  
require ‘rexml/document’  
xml = xml.to\_s.gsub(“utf-16”, “utf-8”)  
doc = REXML::Document.new(xml)  
xml\_data = {}  
doc.root.each\_element(path) do |element|  
element.each\_element do |node|  
puts “name: #{node.name} text: #{node.text}”  
xml\_data[node.name] = [http://node.name/](http://node.name/)node.text  
end  
end  
return xml\_data  
end

–  
Rick DeNatale

My blog on Ruby  
[http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![aidy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/eada6e/32.png) [@aidy](https://www.ruby-forum.com/u/aidy)\
**Post date:** [June 30, 2008, 7:25pm UTC](https://www.ruby-forum.com/t/is-it-possible-to-create-a-hash-dynamically/141803/4 "2008-06-30T19:25:52Z")

</div>

Hi stefano,

On 30 Jun, 17:46, Stefano C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> To do what you want, you should set @xml\_data to an empty hash outside the  
> @xml\_data[node.name] =\> node.text}
> 
> Stefano- Hide quoted text -
> 
> - Show quoted text -

Thanks for the help.

After the syntax change, all elements are found.

Not so sure why my IDE did not pick them all up, the first time I ran  
the change!

Aidy

---

<div class="post-metadata">

**Author:** ![aidy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/eada6e/32.png) [@aidy](https://www.ruby-forum.com/u/aidy)\
**Post date:** [June 30, 2008, 7:18pm UTC](https://www.ruby-forum.com/t/is-it-possible-to-create-a-hash-dynamically/141803/5 "2008-06-30T19:18:49Z")

</div>

On 30 Jun, 17:46, Stefano C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> puts "name: #{node.name} text: #{node.text}"
> 
> ```
> 
> I hope this helps
> 
> Stefano-

Hi Stefano,

Thanks for getting back, but there seems to be a syntax error here:

@xml\_data[node.name] =\> node.text}

I have tried this,

```
 def extract(xml, path)
  require 'rexml/document'
  xml = xml.to_s.gsub("utf-16", "utf-8")
  doc = REXML::Document.new(xml)
  @xml_data = {}
  doc.root.each_element(path) do |element|
      element.each_element do |node|
      puts "name: #{node.name} text: #{node.text}"
      @xml_data[node.name] = node.text
    end
  end
  return @xml_data
end

```

but still get one element in @xml\_data

Regards

Aidy
