Newbie to using builder(for xml markup)

Hi,

I am just trying to understand how builder sorts the content of an xml
node, because no matter how I arrange the options, they appears sorted
differently in the irb.

ids = [“1”,“2”,“3”]
alphas = [“xxx”,“yyy”,“zzz”]

xml = Builder::XmlMarkup.new( :target => $stdout, :indent => 2 )
xml.instruct! :xml, :version => “1.1”, :encoding => “US-ASCII”

ids.each do |num|
xml.programme(:alpha => alphas.fetch(ids.index(num)), :id => num)
end

This prints:


But if I re-arrange the positioning to:

xml.programme(:id => num, :alpha => alphas.fetch(ids.index(num)))

It still produces:


NO CHANGE!!!

Also, is there an easy way to map the values of the arrays together,
than using the fetch method?

THANKS IN ADVANCE!!

Answered BY MYSELF!!

There appears to be a conflict with using the :id value, if you have a
tag attribute named as this, for some reason it inserts it at the very
end.

So using:

ids.each do |num|
xml.programme(:id => num, :alpha => alphas.fetch(ids.index(num)))
end

will print:


but changing, like so:

ids.each do |num|
xml.programme(:num => num, :alpha => alphas.fetch(ids.index(num)))
end

will print:


SO BE CAREFUL WHEN USING “id”

On 5/6/2011 08:50, Brad S. wrote:

end
end

will print:


SO BE CAREFUL WHEN USING “id”

Hello, Brad,

Actually, be careful using hashes (which is what you’re implicitly
doing) if you care about key ordering. The arguments you’re passing to
the programme method are converted into a Hash object by Ruby prior to
being passed. In the Ruby 1.8 series and earlier, the order of the hash
keys is not preserved, so your keys may come out in any order when
they’re enumerated. See what happens if you do this:

ids.each do |num|
xml.programme(:alpha => alphas.fetch(ids.index(num)), :num => num)
end

Most likely you’ll end up with the num attribute followed by the alpha
attribute just like your last example even though the order of them is
switched in my example. If that’s not the case, let us know, but you’ll
probably have to take a look at the source for builder in order to
figure out why.

It’s possible that you’ll get what you want if you switch to Ruby 1.9.2.
The Ruby 1.9 series preserves the order of hash keys based on insertion
order. You may also be able to do what you want in Ruby 1.8 by either
wrapping or extending Hash to make your own Hash-like object that
preserves key order.

This thread may be helpful for you. It even includes a potential
implementation for an order preserving Hash if you’re interested:

http://www.ruby-forum.com/topic/166075

Here’s a gem for such an implementation:

http://rubygems.org/gems/orderedhash

Using that will make your code a little ugly, but it may be worth it if
you’re really concerned about the order of the attributes in your XML.

-Jeremy

Brad S. wrote in post #997015:

I am just trying to understand how builder sorts the content of an xml
node, because no matter how I arrange the options, they appears sorted
differently in the irb.

  1. The ordering of an xml element’s attributes is irrelevant.

  2. There are enough inconsistencies between irb and a real ruby program
    that using irb to troubleshoot code is a waste of time.

ids = [“1”,“2”,“3”]
alphas = [“xxx”,“yyy”,“zzz”]

xml = Builder::XmlMarkup.new( :target => $stdout, :indent => 2 )
xml.instruct! :xml, :version => “1.1”, :encoding => “US-ASCII”

ids.each do |num|
xml.programme(:alpha => alphas.fetch(ids.index(num)), :id => num)
end

Also, is there an easy way to map the values of the arrays together,
than using the fetch method?

ids.each_index do |i|
xml.programme(:alpha => alphas[i], :id => ids[i])
end

ids = [“1”,“2”,“3”]
alphas = [“xxx”,“yyy”,“zzz”]

h = Hash[*alphas.zip(ids).flatten]

p h

–output:–
{“xxx”=>“1”, “yyy”=>“2”, “zzz”=>“3”}

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs