Is it possible to create a hash dynamically?

Hi,

I am trying to build a dynamic hash map

<CODE>
  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
</CODE>

However, the @xml_data is always returning 1 element

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

···

On Monday 30 June 2008, aidy wrote:

Hi,

I am trying to build a dynamic hash map

<CODE>
  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
</CODE>

However, the @xml_data is always returning 1 element

Thanks

Aidy

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/&gt;node\.text
       end
     end
     return xml_data
   end

···

On Mon, Jun 30, 2008 at 12:32 PM, aidy <aidy.lewis@googlemail.com> wrote:

Hi,

I am trying to build a dynamic hash map

<CODE>
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
</CODE>

However, the @xml_data is always returning 1 element

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

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

···

On 30 Jun, 17:46, Stefano Crocco <stefano.cro...@alice.it> wrote:

On Monday 30 June 2008, aidy wrote:

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-

Hi stefano,

···

On 30 Jun, 17:46, Stefano Crocco <stefano.cro...@alice.it> wrote:

On Monday 30 June 2008, aidy wrote:
>
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- 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