CSV to XML questions builder gem

Hi all!

I'm converting a csv file to an xml with the code below. This works
fine. Maybe it can be done differently and better but it works for me.

I have three questions:
1 - Why cant I re-use "csv" within "builder.type" ? If re-use it I dont
get any data.
2 - I would like to add an attribute to builder.type. How can do that? I
want the result to be like <type upgnr="12345"> and then the rest of the
xml..
3 - If I change to an excel file as source. How should I change the
code?

Any suggestions are appreciated. Maybe my code is not so "ruby"? Please
show me an example of how I can improve :slight_smile:

Br
cristian

[code]
require 'csv'
require 'builder'

File.open("testXML.xml","w"){|f|
  builder = Builder::XmlMarkup.new(:target => f, :indent => 2)
  builder.instruct!

  csv = CSV.open('mytest.csv','rb',:headers=>true)

  builder.statusinfo("date"=>"#{Time.now}", "count" =>
"#{csv.readlines.size}")
  builder.type{#, "upgnr"=>"12345"

# Question 1: I would like to use > csv.each do |invoice|
    CSV.open('mytest.csv','rb',:headers=>true).each do |invoice|

      column = invoice[0].split(";")

      builder.status{|b|
        b.custid("#{column[1]}")
        b.invno("#{column[2]}")
        b.date("#{column[4]}")
        b.code("#{column[8]}")
        b.date2("#{column[9]}")
      }
    end
  }
}
[/code]

···

--
Posted via http://www.ruby-forum.com/.

I'm not sure what version of Ruby you're using, but I suspect that the
reason you can't see "csv" is because you're inside the "builder.type{"
block.
http://ruby.about.com/od/newinruby191/a/blockvariscope.htm

Making the variable something like @csv or $csv should make it visible
inside the block, since those are not local variables (instance and
global, respectively).

I suspect that builder.type doesn't work because you've commented out
the rest of that line:

builder.type{#, "upgnr"=>"12345"
Here the "#" makes the rest of the line a comment, and is ignored by the
interpreter.

If you want to read an Excel file, there are several gems that allow you
to do so. Each has their merits. Try this list:
https://www.ruby-toolbox.com/categories/reporting

···

--
Posted via http://www.ruby-forum.com/.

Hi Joel,

Thank you for helping me.

Im using ruby 2.0.0p247

Regarding the variables I have tried @csv and $csv without luck.

In my code above I forgot to delete the outcommented code after the #.
Even if I remove the # it doesnt work. At the moment (with the out
commented line above) the result is: <type> without the attribute
"upgnr".

···

--
Posted via http://www.ruby-forum.com/.

Ok...

The code should look like this to get the attribute in there:

builder.type("upgnr"=>"12345"){...

I dont know what I was thinking about.

Still I have a problem with the scope of that variable. I dont
understand how to "pass" the variable to the block within
builder.type...

There's no parameter called csv within the block so it should refer to
the variable outside the block...Im getting confused..

···

--
Posted via http://www.ruby-forum.com/.

Exactly what error do you get when you try to reference "csv"? Is it
undefined variable, or something else?

···

--
Posted via http://www.ruby-forum.com/.

Sorry for late reply.

Well. I dont get an error message. When I use the variable "csv" inside
the block it seems as it just ignores it. so the result is as executing
this:

[code]
require 'csv'
require 'builder'

File.open("testXML.xml","w"){|f|
  builder = Builder::XmlMarkup.new(:target => f, :indent => 2)
  builder.instruct!

  csv = CSV.open('mytest.csv','rb',:headers=>true)

  builder.statusinfo("date"=>"#{Time.now}", "count" =>
"#{csv.readlines.size}")
  builder.type("upgnr"=>"12345"){

  #Code removed

  }
}
[/code]

···

--
Posted via http://www.ruby-forum.com/.

What happens when you inspect the csv inside that block?
Like this:
puts csv.inspect, csv.length

···

--
Posted via http://www.ruby-forum.com/.

Well...this is the error with suggested inspect and length..

C:\CR - XML convevert>ruby converter_test.rb
converter_test.rb:31:in `block (2 levels) in <main>' undefined method
'length'
for #<CSV:0x2396bc8> (NoMethodError)
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems
se.rb:170:in `call'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems
se.rb:170:in `_nested_structures'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems
se.rb:63:in `tag!'
        from C:/Ruby200/lib/ruby/gems/2.0.0/gems
se.rb:88:in `method_missing'
        from converter_test.rb:29:in `block in <main>'
        from converter_test.rb:19:in `open'
        from converter_test.rb:19:in `<main>'

···

--
Posted via http://www.ruby-forum.com/.

I guess length isn't supported, I thought it was.

Anyway, the good news is that you can see your csv variable!
It's this: #<CSV:0x2396bc8>

···

--
Posted via http://www.ruby-forum.com/.

Yes. Now that I only have puts csv.inspect just above the I can see
whats in there. But why cant I use it?

[code]

....

puts csv.inspect
CSV.open('mytest.csv','rb',:headers=>true).each do |invoice|

      column = invoice[0].split(";")

      builder.status{|b|
        b.custid("#{column[1]}")
        b.invno("#{column[2]}")
        b.date("#{column[4]}")
        b.code("#{column[8]}")
        b.date2("#{column[9]}")
      }
    end

...

[/code]

This gives me:

<#CSV io_type:File io_path:"mytest.csv" encoding:ASCII-8BIT lineno:360
col_s
ep:"," row_sep:"\r\n" quote_char:"\""
headers:["Namn;CustID;InvoiceID;InvoiceDate;F\
xF6rfdat;InvoiceAm;Payedbel;AM;KKL;Date;KK;RK;"]>

csv is:
csv = CSV.open('mytest.csv','rb',:headers=>true)

Cant I do a ".each do |x|" on this variable?

/cristian

···

--
Posted via http://www.ruby-forum.com/.

You should be able to, yes. There shouldn't be any difference between
using the variable and reopening the file, as far as I can see, except
possibly a conflict with opening the file when it's already open.

At this point you should continue entering debugging lines, like this:

puts csv.inspect
csv.each do |invoice|

      puts invoice.inspect

      column = invoice[0].split(";")
      puts column.inspect
      etc, etc....

···

--
Posted via http://www.ruby-forum.com/.

If I try iterate csv it doesnt give anything so everything I do within
the block is just ignored.

I think its some kind of conflict because if I declare a new variable
outside the block it works fine:

csv2 = CSV.open(infile+'.csv','rb',:headers=>true)

The problem arises when I do "csv.readlines.size". After this I cant use
the variable even though if I inspect it there is something in there....

···

--
Posted via http://www.ruby-forum.com/.

This works...

[code]
require 'csv'
require 'builder'

File.open("testXML.xml","w"){|f|
  builder = Builder::XmlMarkup.new(:target => f, :indent => 2)
  builder.instruct!

  csv = CSV.open('mytest.csv','rb',:headers=>true)
  csv2 = CSV.open('mytest.csv','rb',:headers=>true)

  builder.statusinfo("date"=>"#{Time.now}", "count" =>
"#{csv.readlines.size}")
  builder.type{#, "upgnr"=>"12345"

    csv2.each do |invoice|

      column = invoice[0].split(";")

      builder.status{|b|
        b.custid("#{column[1]}")
        b.invno("#{column[2]}")
        b.date("#{column[4]}")
        b.code("#{column[8]}")
        b.date2("#{column[9]}")
      }
    end
  }
}
[/code]

···

--
Posted via http://www.ruby-forum.com/.

Perhaps "readlines" leaves nothing left to iterate through with "each".
I suspect that the csv keeps its current position, meaning you're
already at the end of the file after using "readlines".

···

--
Posted via http://www.ruby-forum.com/.

ok. Thank you for your help Joel.

···

--
Posted via http://www.ruby-forum.com/.

@John: Enable/disable email notification...

Are these topics mixed now?

···

--
Posted via http://www.ruby-forum.com/.

Hello everyone,

Is it good idea to use nested classes if they are small and will be used by parent class only?

Bob

Hello,

Hello everyone,

Is it good idea to use nested classes if they are small and will be used by parent class only?

Sure. There's nothing wrong with that, depends heavily on the use case.

Bob

Panagiotis (atmosx) Atmatzidis

email: atma@convalesco.org
URL: http://www.convalesco.org
GnuPG ID: 0x1A7BFEC5
gpg --keyserver pgp.mit.edu --recv-keys 1A7BFEC5

···

On 7 Οκτ 2013, at 16:47 , Χαράλαμπος Κώστας <root@charkost.gr> wrote:
--
The wise man said: "Never argue with an idiot. They bring you down to their level and beat you with experience."

How do I get removed from this list, please?

···

On 7 October 2013 16:47, Χαράλαμπος Κώστας <root@charkost.gr> wrote:

Hello everyone,

Is it good idea to use nested classes if they are small and will be used
by parent class only?

Bob

Do not thread hijack. Start a new one.

···

On Oct 7, 2013, at 7:47, Χαράλαμπος Κώστας <root@charkost.gr> wrote:

Hello everyone,

Is it good idea to use nested classes if they are small and will be used by parent class only?

Bob