is it possible to create a hash dynamically?

A

aidy

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
 
S

Stefano Crocco

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
 
R

Rick DeNatale

[Note: parts of this message were removed to make it a legal post.]

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


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/>node.text
end
end
return xml_data
end
 
A

aidy

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 replaceit
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,

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
 
A

aidy

Hi stefano,

The problem is in the line

@xml_data = {node.name => node.text}

At each iteration, you discard the old content of the variable and replaceit
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,709
Latest member
AustinMudi

Latest Threads

Top