... >]
== Searching
You can use certain methods to search among the descendants of an element.
Use method REXML::Element#get_elements to retrieve all element children of the element
that match the given +xpath+:
xml_string = <<-EOT
EOT
d = Document.new(xml_string)
d.root.get_elements('//a') # => [ ... >, ]
Use method REXML::Element#get_text with no argument to retrieve the first text node
in the first child:
my_doc = Document.new "some text this is bold! more text
"
text_node = my_doc.root.get_text
text_node.class # => REXML::Text
text_node.to_s # => "some text "
Use the same method with argument +xpath+ to retrieve the first text node
in the first child that matches the xpath:
my_doc.root.get_text(1) # => "this is bold!"
Use method REXML::Element#text with no argument to retrieve the text
from the first text node in the first child:
my_doc = Document.new "some text this is bold! more text
"
text_node = my_doc.root.text
text_node.class # => String
text_node # => "some text "
Use the same method with argument +xpath+ to retrieve the text from the first text node
in the first child that matches the xpath:
my_doc.root.text(1) # => "this is bold!"
Use included method REXML::Node#find_first_recursive
to retrieve the first descendant element
for which the given block returns a truthy value, or +nil+ if none:
doc.root.find_first_recursive do |ele|
ele.name == 'price'
end # => ... >
doc.root.find_first_recursive do |ele|
ele.name == 'nosuch'
end # => nil
== Editing
=== Editing a Document
[Creating a Document]
Create a new document with method REXML::Document::new:
doc = Document.new(source_string)
empty_doc = REXML::Document.new
[Adding to the Document]
Add an XML declaration with method REXML::Document#add
and an argument of type REXML::XMLDecl:
my_doc = Document.new
my_doc.xml_decl.to_s # => ""
my_doc.add(XMLDecl.new('2.0'))
my_doc.xml_decl.to_s # => ""
Add a document type with method REXML::Document#add
and an argument of type REXML::DocType:
my_doc = Document.new
my_doc.doctype.to_s # => ""
my_doc.add(DocType.new('foo'))
my_doc.doctype.to_s # => ""
Add a node of any other REXML type with method REXML::Document#add and an argument
that is not of type REXML::XMLDecl or REXML::DocType:
my_doc = Document.new
my_doc.add(Element.new('foo'))
my_doc.to_s # => ""
Add an existing element as the root element with method REXML::Document#add_element:
ele = Element.new('foo')
my_doc = Document.new
my_doc.add_element(ele)
my_doc.root # =>
Create and add an element as the root element with method REXML::Document#add_element:
my_doc = Document.new
my_doc.add_element('foo')
my_doc.root # =>
=== Editing an Element
==== Creating an Element
Create a new element with method REXML::Element::new:
ele = Element.new('foo') # =>
==== Setting Element Properties
Set the context for an element with method REXML::Element#context=
(see {Element Context}[../context_rdoc.html]):
ele.context # => nil
ele.context = {ignore_whitespace_nodes: :all}
ele.context # => {:ignore_whitespace_nodes=>:all}
Set the parent for an element with inherited method REXML::Child#parent=
ele.parent # => nil
ele.parent = Element.new('bar')
ele.parent # =>
Set the text for an element with method REXML::Element#text=:
ele.text # => nil
ele.text = 'bar'
ele.text # => "bar"
==== Adding to an Element
Add a node as the last child with inherited method REXML::Parent#add (or its alias #push):
ele = Element.new('foo') # =>
ele.push(Text.new('bar'))
ele.push(Element.new('baz'))
ele.children # => ["bar", ]
Add a node as the first child with inherited method REXML::Parent#unshift:
ele = Element.new('foo') # =>
ele.unshift(Element.new('bar'))
ele.unshift(Text.new('baz'))
ele.children # => ["bar", ]
Add an element as the last child with method REXML::Element#add_element:
ele = Element.new('foo') # =>
ele.add_element('bar')
ele.add_element(Element.new('baz'))
ele.children # => [, ]
Add a text node as the last child with method REXML::Element#add_text:
ele = Element.new('foo') # =>
ele.add_text('bar')
ele.add_text(Text.new('baz'))
ele.children # => ["bar", "baz"]
Insert a node before a given node with method REXML::Parent#insert_before:
ele = Element.new('foo') # =>
ele.add_text('bar')
ele.add_text(Text.new('baz'))
ele.children # => ["bar", "baz"]
target = ele[1] # => "baz"
ele.insert_before(target, Text.new('bat'))
ele.children # => ["bar", "bat", "baz"]
Insert a node after a given node with method REXML::Parent#insert_after:
ele = Element.new('foo') # =>
ele.add_text('bar')
ele.add_text(Text.new('baz'))
ele.children # => ["bar", "baz"]
target = ele[0] # => "bar"
ele.insert_after(target, Text.new('bat'))
ele.children # => ["bar", "bat", "baz"]
Add an attribute with method REXML::Element#add_attribute:
ele = Element.new('foo') # =>
ele.add_attribute('bar', 'baz')
ele.add_attribute(Attribute.new('bat', 'bam'))
ele.attributes # => {"bar"=>bar='baz', "bat"=>bat='bam'}
Add multiple attributes with method REXML::Element#add_attributes:
ele = Element.new('foo') # =>
ele.add_attributes({'bar' => 'baz', 'bat' => 'bam'})
ele.add_attributes([['ban', 'bap'], ['bah', 'bad']])
ele.attributes # => {"bar"=>bar='baz', "bat"=>bat='bam', "ban"=>ban='bap', "bah"=>bah='bad'}
Add a namespace with method REXML::Element#add_namespace:
ele = Element.new('foo') # =>
ele.add_namespace('bar')
ele.add_namespace('baz', 'bat')
ele.namespaces # => {"xmlns"=>"bar", "baz"=>"bat"}
==== Deleting from an Element
Delete a specific child object with inherited method REXML::Parent#delete:
ele = Element.new('foo') # =>
ele.add_element('bar')
ele.add_text('baz')
ele.children # => [, "baz"]
target = ele[1] # => "baz"
ele.delete(target) # => "baz"
ele.children # => []
target = ele[0] # =>
ele.delete(target) # =>
ele.children # => []
Delete a child at a specific index with inherited method REXML::Parent#delete_at:
ele = Element.new('foo') # =>
ele.add_element('bar')
ele.add_text('baz')
ele.children # => [, "baz"]
ele.delete_at(1)
ele.children # => []
ele.delete_at(0)
ele.children # => []
Delete all children meeting a specified criterion with inherited method
REXML::Parent#delete_if:
ele = Element.new('foo') # =>
ele.add_element('bar')
ele.add_text('baz')
ele.add_element('bat')
ele.add_text('bam')
ele.children # => [, "baz", , "bam"]
ele.delete_if {|child| child.instance_of?(Text) }
ele.children # => [, ]
Delete an element at a specific 1-based index with method REXML::Element#delete_element:
ele = Element.new('foo') # =>
ele.add_element('bar')
ele.add_text('baz')
ele.add_element('bat')
ele.add_text('bam')
ele.children # => [, "baz", , "bam"]
ele.delete_element(2) # =>
ele.children # => [, "baz", "bam"]
ele.delete_element(1) # =>
ele.children # => ["baz", "bam"]
Delete a specific element with the same method:
ele = Element.new('foo') # =>
ele.add_element('bar')
ele.add_text('baz')
ele.add_element('bat')
ele.add_text('bam')
ele.children # => [, "baz", , "bam"]
target = ele.elements[2] # =>
ele.delete_element(target) # =>
ele.children # => [, "baz", "bam"]
Delete an element matching an xpath using the same method:
ele = Element.new('foo') # =>
ele.add_element('bar')
ele.add_text('baz')
ele.add_element('bat')
ele.add_text('bam')
ele.children # => [, "baz", , "bam"]
ele.delete_element('./bat') # =>
ele.children # => [, "baz", "bam"]
ele.delete_element('./bar') # =>
ele.children # => ["baz", "bam"]
Delete an attribute by name with method REXML::Element#delete_attribute:
ele = Element.new('foo') # =>
ele.add_attributes({'bar' => 'baz', 'bam' => 'bat'})
ele.attributes # => {"bar"=>bar='baz', "bam"=>bam='bat'}
ele.delete_attribute('bam')
ele.attributes # => {"bar"=>bar='baz'}
Delete a namespace with method REXML::Element#delete_namespace:
ele = Element.new('foo') # =>
ele.add_namespace('bar')
ele.add_namespace('baz', 'bat')
ele.namespaces # => {"xmlns"=>"bar", "baz"=>"bat"}
ele.delete_namespace('xmlns')
ele.namespaces # => {} # => {"baz"=>"bat"}
ele.delete_namespace('baz')
ele.namespaces # => {} # => {}
Remove an element from its parent with inherited method REXML::Child#remove:
ele = Element.new('foo') # =>
parent = Element.new('bar') # =>
parent.add_element(ele) # =>
parent.children.size # => 1
ele.remove # =>
parent.children.size # => 0
==== Replacing Nodes
Replace the node at a given 0-based index with inherited method REXML::Parent#[]=:
ele = Element.new('foo') # =>
ele.add_element('bar')
ele.add_text('baz')
ele.add_element('bat')
ele.add_text('bam')
ele.children # => [, "baz", , "bam"]
ele[2] = Text.new('bad') # => "bad"
ele.children # => [, "baz", "bad", "bam"]
Replace a given node with another node with inherited method REXML::Parent#replace_child:
ele = Element.new('foo') # =>
ele.add_element('bar')
ele.add_text('baz')
ele.add_element('bat')
ele.add_text('bam')
ele.children # => [, "baz", , "bam"]
target = ele[2] # =>
ele.replace_child(target, Text.new('bah'))
ele.children # => [, "baz", "bah", "bam"]
Replace +self+ with a given node with inherited method REXML::Child#replace_with:
ele = Element.new('foo') # =>
ele.add_element('bar')
ele.add_text('baz')
ele.add_element('bat')
ele.add_text('bam')
ele.children # => [, "baz", , "bam"]
target = ele[2] # =>
target.replace_with(Text.new('bah'))
ele.children # => [, "baz", "bah", "bam"]
=== Cloning
Create a shallow clone of an element with method REXML::Element#clone.
The clone contains the name and attributes, but not the parent or children:
ele = Element.new('foo')
ele.add_attributes({'bar' => 0, 'baz' => 1})
ele.clone # =>
Create a shallow clone of a document with method REXML::Document#clone.
The XML declaration is copied; the document type and root element are not cloned:
my_xml = ''
my_doc = Document.new(my_xml)
clone_doc = my_doc.clone
my_doc.xml_decl # =>
clone_doc.xml_decl # =>
my_doc.doctype.to_s # => ""
clone_doc.doctype.to_s # => ""
my_doc.root # =>
clone_doc.root # => nil
Create a deep clone of an element with inherited method REXML::Parent#deep_clone.
All nodes and attributes are copied:
doc.to_s.size # => 825
clone = doc.deep_clone
clone.to_s.size # => 825
== Writing the Document
Write a document to an \IO stream (defaults to $stdout)
with method REXML::Document#write:
doc.write
Output:
Everyday Italian
Giada De Laurentiis
2005
30.00
Harry Potter
J K. Rowling
2005
29.99
XQuery Kick Start
James McGovern
Per Bothner
Kurt Cagle
James Linn
Vaidyanathan Nagarajan
2003
49.99
Learning XML
Erik T. Ray
2003
39.95