You want to modify an XML document, or create a new one from scratch.
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] # => "" doc.write($stdout, 1) # # # doc.children[0] # => doc.children[1] # =>… >
To append a text node to the contents of an element, use the
add_text method. This code adds an <agenda> element to the
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) ## # <agenda> # Nothing of importance will be decided. The same tired ideas will be # rehashed yet again. # #
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) #
# # <agenda> # Nothing of importance will be decided. The same tired ideas will be # rehashed yet again. # - Weekly status meetings: improving attendance
# #
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.
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