SitePoint Sponsor |
|
User Tag List
Results 1 to 8 of 8
Thread: building xml
-
Jun 20, 2006, 09:09 #1
- Join Date
- May 2001
- Posts
- 193
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
building xml
I'm having trouble trying to build up an xml file.
basically I'm looping thru an array and I want to append items to a node based on a value.
so if i have an array like:
PHP Code:my_array = [["sam", "string 1"], ["sam", "string 2"], ["joe", "string 1"]]
<people>
<person ="sam">
<dialog>string 1</dialog>
<dialog>string 2</dialog>
</person>
<person ="joe">
<dialog>string 1</dialog>
</person>
</people>
Here's my attempt:
PHP Code:people_listing_xml ="<people>\n"
people_xml = Builder::XmlMarkup.new(:target => people_listing_xml, :indent => 1)
//inside the loop
people_xml.chat "person"=>person do
people_xml.dialog dialog
end
people_listing_xml << "</people>\n"
-
Jun 20, 2006, 10:19 #2
- Join Date
- May 2001
- Posts
- 193
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I guess my question really is how do I append values to any existing node?
So, in my example if I wanted to add some more entries for "sam" I would need to select the person with the id of sam and add an entry.
I know this is probably simple stuff but I'm stumped
-
Jun 20, 2006, 11:46 #3
- Join Date
- Aug 2005
- Posts
- 986
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
I think this function is helpful:
Code:people = [["sam", "a"], ["sam", "b"], ["joe", "c"]] def group(ary) res = {} for ele in ary res[ele[0]] = (res[ele[0]] || []) + [ele[1]] end and res end group(people) # => {"joe"=>["c"], "sam"=>["a", "b"]}
-
Jun 20, 2006, 13:01 #4
- Join Date
- May 2001
- Posts
- 193
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Hey Fenrir, thanks for that.
I'm not sure how it applies to my problem though.
Is it really as hard as I think it is to append to an xml node?
-
Jun 21, 2006, 04:47 #5
- Join Date
- Aug 2005
- Posts
- 986
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Yes. I don't know how builder works exactly, but it seems to be nearly impossible to append to an existing node.
That's why I wrote that function ;-). If you look closely, you see that the function transforms the original array to a hash that's structured like your XML. You should insert a new loop *inside* people_xml.chat "person"=>person do ... end, and add a node for every element in the array of the hash.
Please tell me if this isn't clear.
-
Jun 22, 2006, 06:28 #6
- Join Date
- May 2001
- Posts
- 193
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Hi,
Yes, your method is clear. Just suprised you can not simply append to a node
Thanks
-
Jun 22, 2006, 06:42 #7
- Join Date
- Aug 2005
- Posts
- 986
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Actually it's not strange at all, because builder doesn't create an object model of the xml, but it just creates a string. If you want to append to a node, use REXML, but in your case, this is an overkill.
Also:
Code:people_listing_xml ="<people>\n" people_xml = Builder::XmlMarkup.new(:target => people_listing_xml, :indent => 1) //inside the loop people_xml.chat "person"=>person do people_xml.dialog dialog end people_listing_xml << "</people>\n"
Code:x = Builder::XmlMarkup.new(:indent => 1) x.people { //inside the loop x.chat(:person => person) { x.dialog dialog } }
-
Jun 23, 2006, 16:42 #8
- Join Date
- May 2005
- Posts
- 2
- Mentioned
- 0 Post(s)
- Tagged
- 0 Thread(s)
Code:require 'builder' my_array = [["sam", "string 1"], ["sam", "string 2"], ["joe", "string 1"]] my_hash = my_array.inject(Hash.new { [] }) { |g,p| g[p[0]] <<= p[1]; g } xml = Builder::XmlMarkup.new(:target => (my_output = ''), :indent => 1) xml.people do my_hash.each do |name, dialogs| xml.person :name => name do dialogs.each do |dialog| xml.dialog dialog end end end end print my_output
Code:<people> <person name="joe"> <dialog>string 1</dialog> </person> <person name="sam"> <dialog>string 1</dialog> <dialog>string 2</dialog> </person> </people>
I suppose if you wanted to add a new node you could just:
my_array << ["sam", "some more"]
and generate the xml again.
Bookmarks