Creating and Modifying XML Documents

Problem

You want to modify an XML document, or create a new one from scratch.

Solution

To create an XML document from scratch, just start with an empty Document object.

	require 
exml/document
	require
	doc = REXML::Document.new

To add a new element to an existing document, pass its name and any attributes into its parents add_element method. You don have to create the Element objects yourself.

	meeting = doc.add_element meeting
	meeting_start = Time.local(2006, 10, 31, 13)
	meeting.add_element(	ime, { from => meeting_start,
	 	o => meeting_start + 3600 })

	doc.children[0] # =>  … 
	doc.children[0].children[0]
	# => "

To append a text node to the contents of an element, use the add_text method. This code adds an <agenda> element to the element, and gives it two different text nodes:

	agenda = meeting.add_element agenda
	doc.children[1].children[1] # => <agenda/>

	agenda. 
add_text "Nothing of importance will be decided."
	agenda.add_text " The same tired ideas will be rehashed yet again."

	doc.children[1].children[1] # => <agenda> … 

	doc.write($stdout, 1)
	# 
	# 

Element#text= is a nice shortcut for giving an element a single text node. You can also use to overwrite a documents initial text nodes:

	item1 = agenda.add_element item
	doc.children[1].children[1].children[1] # => 
	item1.text = Weekly status meetings: improving attendance
	doc.children[1].children[1].children[1] # =>  … 
	doc.write($stdout, 1)
	# 
	# 

Discussion

If you can access an element or text node (numerically or with XPath), you can modify or delete it. You can modify an elements name with name=, and modify one of its attributes by assigning to an index of attributes. This code uses these methods to make major changes to a document:

	doc = REXML::Document.new %{
	
	 
	 
	 
	 
	 
	
	}

	root = doc[1] # =>  … 
	root.name = oy

	root.elements[//sugar].name = snails
	root.delete_element(//spice)

	set = root.elements[//set]
	set.attributes["of"] = "snips"
	set.attributes["cardinality"] = some

	root.add_element(set, {of => puppy dog tails, cardinality => some })
	doc.write
	# 
	# 
	# 
	# 
	#
	# 
	# 
	# 

You can delete an attribute with Element#delete_attribute, or by assigning nil to it:

	root.attributes[size] = nil
	doc.write($stdout, 0)
	# 
	# 
	# 
	# …
	# 

You can use methods like replace_with to swap out one node for another:

	doc.elements["//snails"].replace_with(REXML::Element.new("escargot"))

All these methods are convenient, but add_element in particular is not very idiomatic. The cgi library lets you structure method calls and code blocks so that your Ruby code has the same nesting structure as the HTML it generates. Why shouldn you be able to do the same for XML? Heres a new method for Element that makes it possible:

	class REXML::Element
	 def with_element(*args)
	 e = add_element(*args)
	 yield e if block_given?
	 end
	end

Now you can structure your Ruby code the same way you structure your XML:

	doc = REXML::Document.new
	doc.with_element(girl, {size => little}) do |girl|
	 girl.with_element(foods) do |foods|
	 foods.add_element(sugar)
	 foods.add_element(spice)
	 end
	 girl.add_element(set, {of => 
ice things, cardinality => all})
	end

	doc.write($stdout, 0)
	# 
	# 
	# 
	# 
	# 
	# 
	# 

The builder gem also lets you build XML this way.

See Also

  • Recipe 7.10, "Hiding Setup and Cleanup in a Block Method," has an example of using the XmlMarkup class in the builder gem.


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net