Class: REXML::Element
Relationships & Source Files | |
Extension / Inclusion / Inheritance Descendants | |
Subclasses:
|
|
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
|
|
Instance Chain:
|
|
Inherits: |
REXML::Parent
|
Defined in: | lib/rexml/element.rb |
Overview
An REXML::Element object represents an XML element.
An element:
-
Has a name (string).
-
May have a parent (another element).
-
Has zero or more children (other elements, text, CDATA, processing instructions, and comments).
-
Has zero or more siblings (other elements, text, CDATA, processing instructions, and comments).
-
Has zero or more named attributes.
In a Hurry?
If you’re somewhat familiar with XML and have a particular task in mind, you may want to see the tasks pages
, and in particular, the tasks page for elements
.
Name
An element has a name, which is initially set when the element is created:
e = REXML::Element.new('foo')
e.name # => "foo"
The name may be changed:
e.name = 'bar'
e.name # => "bar"
Parent
An element may have a parent.
Its parent may be assigned explicitly when the element is created:
e0 = REXML::Element.new('foo')
e1 = REXML::Element.new('bar', e0)
e1.parent # => <foo> ... </>
Note: the representation of an element always shows the element’s name. If the element has children, the representation indicates that by including an ellipsis (...
).
The parent may be assigned explicitly at any time:
e2 = REXML::Element.new('baz')
e1.parent = e2
e1.parent # => <baz/>
When an element is added as a child, its parent is set automatically:
e1.add_element(e0)
e0.parent # => <bar> ... </>
For an element that has no parent, method parent
returns nil
.
Children
An element has zero or more children. The children are an ordered collection of all objects whose parent is the element itself.
The children may include any combination of elements, text, comments, processing instructions, and CDATA. (This example keeps things clean by controlling whitespace via a #context setting.)
xml_string = <<-EOT
<root>
<ele_0/>
text 0
<!--comment 0-->
<?target_0 pi_0?>
<![CDATA[cdata 0]]>
<ele_1/>
text 1
<!--comment 1-->
<?target_0 pi_1?>
<![CDATA[cdata 1]]>
</root>
EOT
context = {ignore_whitespace_nodes: :all, compress_whitespace: :all}
d = REXML::Document.new(xml_string, context)
root = d.root
root.children.size # => 10
root.each {|child| p "#{child.class}: #{child}" }
"REXML::Element: <ele_0/>"
"REXML::Text: \n text 0\n "
"REXML::Comment: comment 0"
"REXML::Instruction: <?target_0 pi_0?>"
"REXML::CData: cdata 0"
"REXML::Element: <ele_1/>"
"REXML::Text: \n text 1\n "
"REXML::Comment: comment 1"
"REXML::Instruction: <?target_0 pi_1?>"
"REXML::CData: cdata 1"
A child may be added using inherited methods Parent#insert_before or Parent#insert_after:
xml_string = '<root><a/><c/><d/></root>'
d = REXML::Document.new(xml_string)
root = d.root
c = d.root[1] # => <c/>
root.insert_before(c, REXML::Element.new('b'))
root.to_a # => [<a/>, <b/>, <c/>, <d/>]
A child may be replaced using Parent#replace_child:
root.replace_child(c, REXML::Element.new('x'))
root.to_a # => [<a/>, <b/>, <x/>, <d/>]
A child may be removed using Parent#delete:
x = root[2] # => <x/>
root.delete(x)
root.to_a # => [<a/>, <b/>, <d/>]
Siblings
An element has zero or more siblings, which are the other children of the element’s parent.
In the example above, element ele_1
is between a CDATA sibling and a text sibling:
ele_1 = root[5] # => <ele_1/>
ele_1.previous_sibling # => "cdata 0"
ele_1.next_sibling # => "\n text 1\n "
Attributes
An element has zero or more named attributes.
A new element has no attributes:
e = REXML::Element.new('foo')
e.attributes # => {}
Attributes
may be added:
e.add_attribute('bar', 'baz')
e.add_attribute('bat', 'bam')
e.attributes.size # => 2
e['bar'] # => "baz"
e['bat'] # => "bam"
An existing attribute may be modified:
e.add_attribute('bar', 'bad')
e.attributes.size # => 2
e['bar'] # => "bad"
An existing attribute may be deleted:
e.delete_attribute('bar')
e.attributes.size # => 1
e['bar'] # => nil
What’s Here
To begin with, what’s elsewhere?
Class REXML::Element inherits from its ancestor classes:
REXML::Element itself and its ancestors also include modules:
Methods for Creating an Element
- ::new
-
Returns a new empty element.
- #clone
-
Returns a clone of another element.
Methods for Attributes
[attribute_name]
-
Returns an attribute value.
- #add_attribute
-
Adds a new attribute.
- #add_attributes
-
Adds multiple new attributes.
- #attribute
-
Returns the attribute value for a given name and optional namespace.
- #delete_attribute
-
Removes an attribute.
Methods for Children
[index]
-
Returns the child at the given offset.
- #add_element
-
Adds an element as the last child.
- #delete_element
-
Deletes a child element.
- #each_element
-
Calls the given block with each child element.
- #each_element_with_attribute
-
Calls the given block with each child element that meets given criteria, which can include the attribute name.
- #each_element_with_text
-
Calls the given block with each child element that meets given criteria, which can include text.
- #get_elements
-
Returns an array of element children that match a given xpath.
Methods for Text Children
- #add_text
-
Adds a text node to the element.
- #get_text
-
Returns a text node that meets specified criteria.
- #text
-
Returns the text string from the first node that meets specified criteria.
- #texts
-
Returns an array of the text children of the element.
- #text=
-
Adds, removes, or replaces the first text child of the element
Methods for Other Children
- #cdatas
-
Returns an array of the cdata children of the element.
- #comments
-
Returns an array of the comment children of the element.
- #instructions
-
Returns an array of the instruction children of the element.
Methods for Namespaces
- #add_namespace
-
Adds a namespace to the element.
- #delete_namespace
-
Removes a namespace from the element.
- #namespace
-
Returns the string namespace URI for the element.
- #namespaces
-
Returns a hash of all defined namespaces in the element.
- #prefixes
-
Returns an array of the string prefixes (names) of all defined namespaces in the element
Methods for Querying
- #document
-
Returns the document, if any, that the element belongs to.
- #root
-
Returns the most distant element (not document) ancestor of the element.
- #root_node
-
Returns the most distant ancestor of the element.
- #xpath
-
Returns the string xpath to the element relative to the most distant parent
- #has_attributes?
-
Returns whether the element has attributes.
- #has_elements?
-
Returns whether the element has elements.
- #has_text?
-
Returns whether the element has text.
- #next_element
-
Returns the next sibling that is an element.
- #previous_element
-
Returns the previous sibling that is an element.
- #raw
-
Returns whether raw mode is set for the element.
- #whitespace
-
Returns whether whitespace is respected for the element.
- #ignore_whitespace_nodes
-
Returns whether whitespace nodes are to be ignored for the element.
- #node_type
-
Returns symbol
:element
.
One More Method
- #inspect
-
Returns a string representation of the element.
Accessors
- #elements
-
Returns the
Elements
object for the element. - #attributes
-
Returns the
Attributes
object for the element. - #context
-
Returns or sets the context hash for the element.
Constant Summary
-
UNDEFINED =
The default name
"UNDEFINED"
XMLTokens
- Included
NAME, NAMECHAR, NAME_CHAR, NAME_START_CHAR, NAME_STR, NCNAME_STR, NMTOKEN, NMTOKENS, REFERENCE
Namespace
- Included
Class Method Summary
-
.new(name = 'UNDEFINED', parent = nil, context = nil) ⇒ Element
constructor
Returns a new REXML::Element object.
Parent
- Inherited
.new | Constructor. |
Child
- Inherited
.new | Constructor. |
Instance Attribute Summary
-
#attributes
readonly
Mechanisms for accessing attributes and child elements of this element.
-
#context
rw
The context holds information about the processing environment, such as whitespace handling.
-
#elements
readonly
Mechanisms for accessing attributes and child elements of this element.
-
#has_attributes? ⇒ Boolean
readonly
Returns
true
if the element has attributes,false
otherwise: -
#has_elements? ⇒ Boolean
readonly
Returns
true
if the element has one or more element children,false
otherwise: -
#has_text? ⇒ Boolean
readonly
Returns
true
if the element has one or more text noded,false
otherwise:
Namespace
- Included
#expanded_name | The name of the object, valid if set. |
#local_name | Alias for Namespace#name. |
#name | The name of the object, valid if set. |
#name= | Sets the name and the expanded name. |
#prefix | The expanded name of the object, valid if name is set. |
Parent
- Inherited
Child
- Inherited
#next_sibling | Alias for Node#next_sibling_node. |
#next_sibling= | Sets the next sibling of this child. |
#parent | The Parent of this object. |
#parent= | Sets the parent of this child to the supplied argument. |
#previous_sibling | Alias for Node#previous_sibling_node. |
#previous_sibling= | Sets the previous sibling of this child. |
Node
- Included
Instance Method Summary
-
#[](index) ⇒ Object
With integer argument
index
given, returns the child at offsetindex
, ornil
if none: -
#add_attribute(name, value) ⇒ value
Adds an attribute to this element, overwriting any existing attribute by the same name.
-
#add_attributes(hash) ⇒ Hash
Adds zero or more attributes to the element; returns the argument.
-
#add_element(name, attributes = nil) ⇒ Element
Adds a child element, optionally setting attributes on the added element; returns the added element.
-
#add_namespace(prefix, uri = nil) ⇒ self
Adds a namespace to the element; returns
self
. -
#add_text(string) ⇒ nil
Adds text to the element.
-
#attribute(name, namespace = nil)
Returns the string value for the given attribute name.
-
#cdatas ⇒ array_of_cdata_children
Returns a frozen array of the
CData
children of the element: -
#clone ⇒ Element
Returns a shallow copy of the element, containing the name and attributes, but not the parent or children:
-
#comments ⇒ array_of_comment_children
Returns a frozen array of the
Comment
children of the element: -
#delete_attribute(name) ⇒ removed_attribute?
Removes a named attribute if it exists; returns the removed attribute if found, otherwise
nil
: -
#delete_element(index) ⇒ Element?
Deletes a child element.
-
#delete_namespace(namespace = 'xmlns') ⇒ self
Removes a namespace from the element.
-
#document ⇒ document?
If the element is part of a document, returns that document:
-
#each_element {|e| ... }
Calls the given block with each child element:
-
#each_element_with_attribute(attr_name, value = nil, max = 0, xpath = nil) {|e| ... }
Calls the given block with each child element that meets given criteria.
-
#each_element_with_text(text = nil, max = 0, xpath = nil) {|e| ... }
Calls the given block with each child element that meets given criteria.
-
#get_elements(xpath)
Returns an array of the elements that match the given #xpath:
-
#get_text(xpath = nil) ⇒ text_node?
Returns the first text node child in a specified element, if it exists,
nil
otherwise. -
#ignore_whitespace_nodes
Returns
true
if whitespace nodes are ignored for the element. -
#inspect ⇒ String
Returns a string representation of the element.
-
#instructions ⇒ array_of_instruction_children
Returns a frozen array of the
Instruction
children of the element: -
#namespace(prefix = nil) ⇒ string_uri?
Returns the string namespace URI for the element, possibly deriving from one of its ancestors.
-
#namespaces ⇒ array_of_namespace_names
Returns a hash of all defined namespaces in the element and its ancestors:
-
#next_element
Returns the next sibling that is an element if it exists,
niL
otherwise: -
#node_type ⇒ Element
Returns symbol
:element
: -
#prefixes ⇒ array_of_namespace_prefixes
Returns an array of the string prefixes (names) of all defined namespaces in the element and its ancestors:
-
#previous_element
Returns the previous sibling that is an element if it exists,
niL
otherwise: -
#raw
Returns
true
if raw mode is set for the element. -
#root ⇒ Element
Returns the most distant element (not document) ancestor of the element:
-
#root_node ⇒ document, Element
Returns the most distant ancestor of
self
. -
#text(xpath = nil) ⇒ text_string?
Returns the text string from the first text node child in a specified element, if it exists,
nil
otherwise. -
#text=(string) ⇒ String
Adds, replaces, or removes the first text node child in the element.
-
#texts ⇒ array_of_text_children
Returns a frozen array of the
Text
children of the element: -
#whitespace
Returns
true
if whitespace is respected for this element,false
otherwise. -
#write(output = $stdout, indent = -1,, transitive = false, ie_hack = false)
DEPRECATED See
Formatters
-
#xpath ⇒ string_xpath
Returns the string xpath to the element relative to the most distant parent:
- #__to_xpath_helper(node) private
-
#each_with_something(test, max = 0, name = nil)
private
A private helper method.
Namespace
- Included
#fully_expanded_name | Fully expand the name, even if the prefix wasn’t specified in the source file. |
#has_name? | Compares names optionally WITH namespaces. |
Parent
- Inherited
#<< | Alias for Parent#push. |
#[] | Fetches a child at a given index. |
#[]= | Set an index entry. |
#add, | |
#children | Alias for Parent#to_a. |
#deep_clone | Deeply clones this object. |
#delete, #delete_at, #delete_if, #each, | |
#each_child | Alias for Parent#each. |
#each_index, | |
#index | Fetches the index of a given child of this parent. |
#insert_after | Inserts an child after another child child2 will be inserted after child1 in the child list of the parent. |
#insert_before | Inserts an child before another child child2 will be inserted before child1 in the child list of the parent. |
#length | Alias for Parent#size. |
#push | Alias for Parent#add. |
#replace_child | Replaces one child with another, making sure the nodelist is correct |
#size, #to_a, #unshift |
Child
- Inherited
#bytes | This doesn’t yet handle encodings. |
#document |
|
#remove | Removes this child from the parent. |
#replace_with | Replaces this object with another object. |
Node
- Included
#each_recursive | Visit all subnodes of |
#find_first_recursive | Find (and return) first subnode (recursively) for which the block evaluates to true. |
#indent, | |
#index_in_parent | Returns the position that |
#next_sibling_node, #previous_sibling_node, | |
#to_s |
|
Constructor Details
.new(name = 'UNDEFINED', parent = nil, context = nil) ⇒ Element
.new(element, parent = nil, context = nil) ⇒ Element
Element
.new(element, parent = nil, context = nil) ⇒ Element
Returns a new REXML::Element object.
When no arguments are given, returns an element with name 'UNDEFINED'
:
e = REXML::Element.new # => <UNDEFINED/>
e.class # => REXML::Element
e.name # => "UNDEFINED"
When only argument name
is given, returns an element of the given name:
REXML::Element.new('foo') # => <foo/>
When only argument element
is given, it must be an REXML::Element object; returns a shallow copy of the given element:
e0 = REXML::Element.new('foo')
e1 = REXML::Element.new(e0) # => <foo/>
When argument parent
is also given, it must be an Parent
object:
e = REXML::Element.new('foo', REXML::Parent.new)
e.parent # => #<REXML::Parent @parent=nil, @children=[<foo/>]>
When argument #context is also given, it must be a hash representing the context for the element; see
:Element
Context
e = REXML::Element.new('foo', nil, {raw: :all})
e.context # => {:raw=>:all}
# File 'lib/rexml/element.rb', line 319
def initialize( arg = UNDEFINED, parent=nil, context=nil ) super(parent) @elements = Elements.new(self) @attributes = Attributes.new(self) @context = context if arg.kind_of? String self.name = arg elsif arg.kind_of? Element self.name = arg. arg.attributes.each_attribute{ |attribute| @attributes << Attribute.new( attribute ) } @context = arg.context end end
Instance Attribute Details
#attributes (readonly)
Mechanisms for accessing attributes and child elements of this element.
# File 'lib/rexml/element.rb', line 278
attr_reader :attributes, :elements
#context (rw)
The context holds information about the processing environment, such as whitespace handling.
# File 'lib/rexml/element.rb', line 281
attr_accessor :context
#elements (readonly)
Mechanisms for accessing attributes and child elements of this element.
# File 'lib/rexml/element.rb', line 278
attr_reader :attributes, :elements
#has_attributes? ⇒ Boolean
(readonly)
# File 'lib/rexml/element.rb', line 1315
def has_attributes? return !@attributes.empty? end
#has_elements? ⇒ Boolean
(readonly)
# File 'lib/rexml/element.rb', line 794
def has_elements? !@elements.empty? end
#has_text? ⇒ Boolean
(readonly)
# File 'lib/rexml/element.rb', line 1002
def has_text? not text().nil? end
Instance Method Details
#[](index) ⇒ Object
#[](attr_name) ⇒ attr_value
#[](attr_sym) ⇒ attr_value
Object
#[](attr_name) ⇒ attr_value
#[](attr_sym) ⇒ attr_value
With integer argument index
given, returns the child at offset index
, or nil
if none:
d = REXML::Document.new '><root><a/>text<b/>more<c/></root>'
root = d.root
(0..root.size).each do |index|
node = root[index]
p "#{index}: #{node} (#{node.class})"
end
"0: <a/> (REXML::Element)"
"1: text (REXML::Text)"
"2: <b/> (REXML::Element)"
"3: more (REXML::Text)"
"4: <c/> (REXML::Element)"
"5: (NilClass)"
With string argument attr_name
given, returns the string value for the given attribute name if it exists, otherwise nil
:
d = REXML::Document.new('<root attr="value"></root>')
root = d.root
root['attr'] # => "value"
root['nosuch'] # => nil
With symbol argument attr_sym
given, returns [attr_sym.to_s]
:
root[:attr] # => "value"
root[:nosuch] # => nil
# File 'lib/rexml/element.rb', line 1246
def [](name_or_index) case name_or_index when String attributes[name_or_index] when Symbol attributes[name_or_index.to_s] else super end end
#__to_xpath_helper(node) (private)
[ GitHub ]
#add_attribute(name, value) ⇒ value
#add_attribute(attribute) ⇒ attribute
value
#add_attribute(attribute) ⇒ attribute
Adds an attribute to this element, overwriting any existing attribute by the same name.
With string argument name
and object value
are given, adds the attribute created with that name and value:
e = REXML::Element.new
e.add_attribute('attr', 'value') # => "value"
e['attr'] # => "value"
e.add_attribute('attr', 'VALUE') # => "VALUE"
e['attr'] # => "VALUE"
With only attribute object #attribute given, adds the given attribute:
a = REXML::Attribute.new('attr', 'value')
e.add_attribute(a) # => attr='value'
e['attr'] # => "value"
a = REXML::Attribute.new('attr', 'VALUE')
e.add_attribute(a) # => attr='VALUE'
e['attr'] # => "VALUE"
# File 'lib/rexml/element.rb', line 1345
def add_attribute( key, value=nil ) if key.kind_of? Attribute @attributes << key else @attributes[key] = value end end
#add_attributes(hash) ⇒ Hash
#add_attributes(array)
Hash
#add_attributes(array)
Adds zero or more attributes to the element; returns the argument.
If hash argument hash
is given, each key must be a string; adds each attribute created with the key/value pair:
e = REXML::Element.new
h = {'foo' => 'bar', 'baz' => 'bat'}
e.add_attributes(h)
If argument array
is given, each array member must be a 2-element array <tt>[name, value]; each name must be a string:
e = REXML::Element.new
a = [['foo' => 'bar'], ['baz' => 'bat']]
e.add_attributes(a)
# File 'lib/rexml/element.rb', line 1376
def add_attributes hash if hash.kind_of? Hash hash.each_pair {|key, value| @attributes[key] = value } elsif hash.kind_of? Array hash.each { |value| @attributes[ value[0] ] = value[1] } end end
#add_element(name, attributes = nil) ⇒ Element
#add_element(element, attributes = nil) ⇒ Element
Element
#add_element(element, attributes = nil) ⇒ Element
Adds a child element, optionally setting attributes on the added element; returns the added element.
With string argument name
, creates a new element with that name and adds the new element as a child:
e0 = REXML::Element.new('foo')
e0.add_element('bar')
e0[0] # => <bar/>
With argument name
and hash argument #attributes, sets attributes on the new element:
e0.add_element('baz', {'bat' => '0', 'bam' => '1'})
e0[1] # => <baz bat='0' bam='1'/>
With element argument element
, adds that element as a child:
e0 = REXML::Element.new('foo')
e1 = REXML::Element.new('bar')
e0.add_element(e1)
e0[0] # => <bar/>
With argument element
and hash argument #attributes, sets attributes on the added element:
e0.add_element(e1, {'bat' => '0', 'bam' => '1'})
e0[1] # => <bar bat='0' bam='1'/>
# File 'lib/rexml/element.rb', line 732
def add_element element, attrs=nil raise "First argument must be either an element name, or an Element object" if element.nil? el = @elements.add(element) attrs.each do |key, value| el.attributes[key]=value end if attrs.kind_of? Hash el end
#add_namespace(prefix, uri = nil) ⇒ self
Adds a namespace to the element; returns self
.
With the single argument prefix
, adds a namespace using the given prefix
and the namespace URI:
e = REXML::Element.new('foo')
e.add_namespace('bar')
e.namespaces # => {"xmlns"=>"bar"}
With both arguments prefix
and uri
given, adds a namespace using both arguments:
e.add_namespace('baz', 'bat')
e.namespaces # => {"xmlns"=>"bar", "baz"=>"bat"}
# File 'lib/rexml/element.rb', line 655
def add_namespace( prefix, uri=nil ) unless uri @attributes["xmlns"] = prefix else prefix = "xmlns:#{prefix}" unless prefix =~ /^xmlns:/ @attributes[ prefix ] = uri end self end
#add_text(string) ⇒ nil
#add_text(text_node) ⇒ self
nil
#add_text(text_node) ⇒ self
Adds text to the element.
When string argument string
is given, returns nil
.
If the element has no child text node, creates a REXML::Text object using the string, honoring the current settings for whitespace and raw, then adds that node to the element:
d = REXML::Document.new('<a><b/></a>')
a = d.root
a.add_text('foo')
a.to_a # => [<b/>, "foo"]
If the element has child text nodes, appends the string to the last text node:
d = REXML::Document.new('<a>foo<b/>bar</a>')
a = d.root
a.add_text('baz')
a.to_a # => ["foo", <b/>, "barbaz"]
a.add_text('baz')
a.to_a # => ["foo", <b/>, "barbazbaz"]
When text node argument text_node
is given, appends the node as the last text node in the element; returns self
:
d = REXML::Document.new('<a>foo<b/>bar</a>')
a = d.root
a.add_text(REXML::Text.new('baz'))
a.to_a # => ["foo", <b/>, "bar", "baz"]
a.add_text(REXML::Text.new('baz'))
a.to_a # => ["foo", <b/>, "bar", "baz", "baz"]
#attribute(name, namespace = nil)
Returns the string value for the given attribute name.
With only argument name
given, returns the value of the named attribute if it exists, otherwise nil
:
xml_string = <<-EOT
<root xmlns="ns0">
<a xmlns="ns1" attr="value"></a>
<b xmlns="ns2" attr="value"></b>
<c attr="value"/>
</root>
EOT
d = REXML::Document.new(xml_string)
root = d.root
a = root[1] # => <a xmlns='ns1' attr='value'/>
a.attribute('attr') # => attr='value'
a.attribute('nope') # => nil
With arguments name
and #namespace given, returns the value of the named attribute if it exists, otherwise nil
:
xml_string = "<root xmlns:a='a' a:x='a:x' x='x'/>"
document = REXML::Document.new(xml_string)
document.root.attribute("x") # => x='x'
document.root.attribute("x", "a") # => a:x='a:x'
# File 'lib/rexml/element.rb', line 1287
def attribute( name, namespace=nil ) prefix = namespaces.key(namespace) if namespace prefix = nil if prefix == 'xmlns' ret_val = attributes.get_attribute( prefix ? "#{prefix}:#{name}" : name ) return ret_val unless ret_val.nil? return nil if prefix.nil? # now check that prefix'es namespace is not the same as the # default namespace return nil unless ( namespaces[ prefix ] == namespaces[ 'xmlns' ] ) attributes.get_attribute( name ) end
#cdatas ⇒ array_of_cdata_children
# File 'lib/rexml/element.rb', line 1420
def cdatas find_all { |child| child.kind_of? CData }.freeze end
#clone ⇒ Element
Returns a shallow copy of the element, containing the name and attributes, but not the parent or children:
e = REXML::Element.new('foo')
e.add_attributes({'bar' => 0, 'baz' => 1})
e.clone # => <foo bar='0' baz='1'/>
# File 'lib/rexml/element.rb', line 383
def clone self.class.new self end
#comments ⇒ array_of_comment_children
Returns a frozen array of the Comment
children of the element:
xml_string = <<-EOT
<root>
<!--foo-->
<!--bar-->
</root>
EOT
d = REXML::Document.new(xml_string)
cs = d.root.comments
cs.frozen? # => true
cs.map {|c| c.class } # => [REXML::Comment, REXML::Comment]
cs.map {|c| c.to_s } # => ["foo", "bar"]
# File 'lib/rexml/element.rb', line 1441
def comments find_all { |child| child.kind_of? Comment }.freeze end
#delete_attribute(name) ⇒ removed_attribute
?
Removes a named attribute if it exists; returns the removed attribute if found, otherwise nil
:
e = REXML::Element.new('foo')
e.add_attribute('bar', 'baz')
e.delete_attribute('bar') # => <bar/>
e.delete_attribute('bar') # => nil
# File 'lib/rexml/element.rb', line 1395
def delete_attribute(key) attr = @attributes.get_attribute(key) attr.remove unless attr.nil? end
#delete_element(index) ⇒ Element
?
#delete_element(element) ⇒ Element
?
#delete_element(xpath) ⇒ Element
?
Element
?
#delete_element(element) ⇒ Element
?
#delete_element(xpath) ⇒ Element
?
Deletes a child element.
When 1-based integer argument index
is given, removes and returns the child element at that offset if it exists; indexing does not include text nodes; returns nil
if the element does not exist:
d = REXML::Document.new '<a><b/>text<c/></a>'
a = d.root # => <a> ... </>
a.delete_element(1) # => <b/>
a.delete_element(1) # => <c/>
a.delete_element(1) # => nil
When element argument element
is given, removes and returns that child element if it exists, otherwise returns nil
:
d = REXML::Document.new '<a><b/>text<c/></a>'
a = d.root # => <a> ... </>
c = a[2] # => <c/>
a.delete_element(c) # => <c/>
a.delete_element(c) # => nil
When xpath argument #xpath is given, removes and returns the element at xpath if it exists, otherwise returns nil
:
d = REXML::Document.new '<a><b/>text<c/></a>'
a = d.root # => <a> ... </>
a.delete_element('//c') # => <c/>
a.delete_element('//c') # => nil
# File 'lib/rexml/element.rb', line 778
def delete_element element @elements.delete element end
#delete_namespace(namespace = 'xmlns') ⇒ self
Removes a namespace from the element.
With no argument, removes the default namespace:
d = REXML::Document.new "<a xmlns:foo='bar' xmlns='twiddle'/>"
d.to_s # => "<a xmlns:foo='bar' xmlns='twiddle'/>"
d.root.delete_namespace # => <a xmlns:foo='bar'/>
d.to_s # => "<a xmlns:foo='bar'/>"
With argument #namespace, removes the specified namespace:
d.root.delete_namespace('foo')
d.to_s # => "<a/>"
Does nothing if no such namespace is found:
d.root.delete_namespace('nosuch')
d.to_s # => "<a/>"
#document ⇒ document?
If the element is part of a document, returns that document:
d = REXML::Document.new('<a><b><c/></b></a>')
top_element = d.first
child = top_element.first
top_element.document == d # => true
child.document == d # => true
If the element is not part of a document, returns nil
:
REXML::Element.new.document # => nil
For a document, returns self
:
d.document == d # => true
Related: #root, #root_node.
# File 'lib/rexml/element.rb', line 475
def document rt = root rt.parent if rt end
#each_element {|e| ... }
#each_element_with_attribute(attr_name, value = nil, max = 0, xpath = nil) {|e| ... }
Calls the given block with each child element that meets given criteria.
When only string argument attr_name
is given, calls the block with each child element that has that attribute:
d = REXML::Document.new '<a><b id="1"/><c id="2"/><d id="1"/><e/></a>'
a = d.root
a.each_element_with_attribute('id') {|e| p e }
<b id='1'/>
<c id='2'/>
<d id='1'/>
With argument attr_name
and string argument value
given, calls the block with each child element that has that attribute with that value:
a.each_element_with_attribute('id', '1') {|e| p e }
<b id='1'/>
<d id='1'/>
With arguments attr_name
, value
, and integer argument max
given, calls the block with at most max
child elements:
a.each_element_with_attribute('id', '1', 1) {|e| p e }
<b id='1'/>
With all arguments given, including #xpath, calls the block with only those child elements that meet the first three criteria, and also match the given #xpath:
a.each_element_with_attribute('id', '1', 2, '//d') {|e| p e }
<d id='1'/>
# File 'lib/rexml/element.rb', line 847
def each_element_with_attribute( key, value=nil, max=0, name=nil, &block ) # :yields: Element each_with_something( proc {|child| if value.nil? child.attributes[key] != nil else child.attributes[key]==value end }, max, name, &block ) end
#each_element_with_text(text = nil, max = 0, xpath = nil) {|e| ... }
Calls the given block with each child element that meets given criteria.
With no arguments, calls the block with each child element that has text:
d = REXML::Document.new '<a><b>b</b><c>b</c><d>d</d><e/></a>'
a = d.root
a.each_element_with_text {|e| p e }
<b> ... </>
<c> ... </>
<d> ... </>
With the single string argument #text, calls the block with each element that has exactly that text:
a.each_element_with_text('b') {|e| p e }
<b> ... </>
<c> ... </>
With argument #text and integer argument max
, calls the block with at most max
elements:
a.each_element_with_text('b', 1) {|e| p e }
<b> ... </>
With all arguments given, including #xpath, calls the block with only those child elements that meet the first two criteria, and also match the given #xpath:
a.each_element_with_text('b', 2, '//c') {|e| p e }
<c> ... </>
#each_with_something(test, max = 0, name = nil) (private)
A private helper method
# File 'lib/rexml/element.rb', line 1536
def each_with_something( test, max=0, name=nil ) num = 0 @elements.each( name ){ |child| yield child if test.call(child) and num += 1 return if max>0 and num == max } end
#get_elements(xpath)
#get_text(xpath = nil) ⇒ text_node
?
Returns the first text node child in a specified element, if it exists, nil
otherwise.
With no argument, returns the first text node from self
:
d = REXML::Document.new "<p>some text <b>this is bold!</b> more text</p>"
d.root.get_text.class # => REXML::Text
d.root.get_text # => "some text "
With argument #xpath, returns the first text node from the element that matches #xpath:
d.root.get_text(1) # => "this is bold!"
# File 'lib/rexml/element.rb', line 1053
def get_text path = nil rv = nil if path element = @elements[ path ] rv = element.get_text unless element.nil? else rv = @children.find { |node| node.kind_of? Text } end return rv end
#ignore_whitespace_nodes
Returns true
if whitespace nodes are ignored for the element.
See
.Element
Context
# File 'lib/rexml/element.rb', line 513
def ignore_whitespace_nodes @ignore_whitespace_nodes = false if @context if @context[:ignore_whitespace_nodes] @ignore_whitespace_nodes = (@context[:ignore_whitespace_nodes] == :all or @context[:ignore_whitespace_nodes].include? ) end end end
#inspect ⇒ String
Returns a string representation of the element.
For an element with no attributes and no children, shows the element name:
REXML::Element.new.inspect # => "<UNDEFINED/>"
Shows attributes, if any:
e = REXML::Element.new('foo')
e.add_attributes({'bar' => 0, 'baz' => 1})
e.inspect # => "<foo bar='0' baz='1'/>"
Shows an ellipsis (...
), if there are child elements:
e.add_element(REXML::Element.new('bar'))
e.add_element(REXML::Element.new('baz'))
e.inspect # => "<foo bar='0' baz='1'> ... </>"
# File 'lib/rexml/element.rb', line 358
def inspect rv = "<#@expanded_name" @attributes.each_attribute do |attr| rv << " " attr.write( rv, 0 ) end if children.size > 0 rv << "> ... </>" else rv << "/>" end end
#instructions ⇒ array_of_instruction_children
Returns a frozen array of the Instruction
children of the element:
xml_string = <<-EOT
<root>
<?target0 foo?>
<?target1 bar?>
</root>
EOT
d = REXML::Document.new(xml_string)
is = d.root.instructions
is.frozen? # => true
is.map {|i| i.class } # => [REXML::Instruction, REXML::Instruction]
is.map {|i| i.to_s } # => ["<?target0 foo?>", "<?target1 bar?>"]
# File 'lib/rexml/element.rb', line 1462
def instructions find_all { |child| child.kind_of? Instruction }.freeze end
#namespace(prefix = nil) ⇒ string_uri
?
Returns the string namespace URI for the element, possibly deriving from one of its ancestors.
xml_string = <<-EOT
<root>
<a xmlns='1' xmlns:y='2'>
<b/>
<c xmlns:z='3'/>
</a>
</root>
EOT
d = REXML::Document.new(xml_string)
b = d.elements['//b']
b.namespace # => "1"
b.namespace('y') # => "2"
b.namespace('nosuch') # => nil
# File 'lib/rexml/element.rb', line 618
def namespace(prefix=nil) if prefix.nil? prefix = prefix() end if prefix == '' prefix = "xmlns" else prefix = "xmlns:#{prefix}" unless prefix[0,5] == 'xmlns' end ns = nil target = self while ns.nil? and target ns = target.attributes[prefix] target = target.parent end ns = '' if ns.nil? and prefix == 'xmlns' return ns end
#namespaces ⇒ array_of_namespace_names
Returns a hash of all defined namespaces in the element and its ancestors:
xml_string = <<-EOT
<root>
<a xmlns:x='1' xmlns:y='2'>
<b/>
<c xmlns:z='3'/>
</a>
</root>
EOT
d = REXML::Document.new(xml_string)
d.elements['//a'].namespaces # => {"x"=>"1", "y"=>"2"}
d.elements['//b'].namespaces # => {"x"=>"1", "y"=>"2"}
d.elements['//c'].namespaces # => {"x"=>"1", "y"=>"2", "z"=>"3"}
# File 'lib/rexml/element.rb', line 591
def namespaces namespaces = {} namespaces = parent.namespaces if parent namespaces = namespaces.merge( attributes.namespaces ) return namespaces end
#next_element
# File 'lib/rexml/element.rb', line 963
def next_element element = next_sibling element = element.next_sibling until element.nil? or element.kind_of? Element return element end
#node_type ⇒ Element
# File 'lib/rexml/element.rb', line 1168
def node_type :element end
#prefixes ⇒ array_of_namespace_prefixes
Returns an array of the string prefixes (names) of all defined namespaces in the element and its ancestors:
xml_string = <<-EOT
<root>
<a xmlns:x='1' xmlns:y='2'>
<b/>
<c xmlns:z='3'/>
</a>
</root>
EOT
d = REXML::Document.new(xml_string, {compress_whitespace: :all})
d.elements['//a'].prefixes # => ["x", "y"]
d.elements['//b'].prefixes # => ["x", "y"]
d.elements['//c'].prefixes # => ["x", "y", "z"]
# File 'lib/rexml/element.rb', line 565
def prefixes prefixes = [] prefixes = parent.prefixes if parent prefixes |= attributes.prefixes return prefixes end
#previous_element
# File 'lib/rexml/element.rb', line 979
def previous_element element = previous_sibling element = element.previous_sibling until element.nil? or element.kind_of? Element return element end
#raw
Returns true
if raw mode is set for the element.
See
.Element
Context
The evaluation is tested against expanded_name
, and so is namespace sensitive.
# File 'lib/rexml/element.rb', line 533
def raw @raw = (@context and @context[:raw] and (@context[:raw] == :all or @context[:raw].include? )) @raw end
#root ⇒ Element
Returns the most distant element (not document) ancestor of the element:
d = REXML::Document.new('<a><b><c/></b></a>')
top_element = d.first
child = top_element.first
top_element.root == top_element # => true
child.root == top_element # => true
For a document, returns the topmost element:
d.root == top_element # => true
Related: #root_node, #document.
#root_node ⇒ document, Element
Returns the most distant ancestor of self
.
When the element is part of a document, returns the root node of the document. Note that the root node is different from the document element; in this example a
is document element and the root node is its parent:
d = REXML::Document.new('<a><b><c/></b></a>')
top_element = d.first # => <a> ... </>
child = top_element.first # => <b> ... </>
d.root_node == d # => true
top_element.root_node == d # => true
child.root_node == d # => true
When the element is not part of a document, but does have ancestor elements, returns the most distant ancestor element:
e0 = REXML::Element.new('foo')
e1 = REXML::Element.new('bar')
e1.parent = e0
e2 = REXML::Element.new('baz')
e2.parent = e1
e2.root_node == e0 # => true
When the element has no ancestor elements, returns self
:
e = REXML::Element.new('foo')
e.root_node == e # => true
# File 'lib/rexml/element.rb', line 422
def root_node parent.nil? ? self : parent.root_node end
#text(xpath = nil) ⇒ text_string
?
Returns the text string from the first text node child in a specified element, if it exists, nil
otherwise.
With no argument, returns the text from the first text node in self
:
d = REXML::Document.new "<p>some text <b>this is bold!</b> more text</p>"
d.root.text.class # => String
d.root.text # => "some text "
With argument #xpath, returns text from the first text node in the element that matches #xpath:
d.root.text(1) # => "this is bold!"
Note that an element may have multiple text nodes, possibly separated by other non-text children, as above. Even so, the returned value is the string text from the first such node.
Note also that the text note is retrieved by method get_text, and so is always normalized text.
# File 'lib/rexml/element.rb', line 1030
def text( path = nil ) rv = get_text(path) return rv.value unless rv.nil? nil end
#text=(string) ⇒ String
#text=(nil) ⇒ nil
String
#text=(nil) ⇒ nil
Adds, replaces, or removes the first text node child in the element.
With string argument string
, creates a new REXML::Text node containing that string, honoring the current settings for whitespace and row, then places the node as the first text child in the element; returns string
.
If the element has no text child, the text node is added:
d = REXML::Document.new '<a><b/></a>'
d.root.text = 'foo' #-> '<a><b/>foo</a>'
If the element has a text child, it is replaced:
d.root.text = 'bar' #-> '<a><b/>bar</a>'
With argument nil
, removes the first text child:
d.root.text = nil #-> '<a><b/><c/></a>'
# File 'lib/rexml/element.rb', line 1089
def text=( text ) if text.kind_of? String text = Text.new( text, whitespace(), nil, raw() ) elsif !text.nil? and !text.kind_of? Text text = Text.new( text.to_s, whitespace(), nil, raw() ) end old_text = get_text if text.nil? old_text.remove unless old_text.nil? else if old_text.nil? self << text else old_text.replace_with( text ) end end return self end
#texts ⇒ array_of_text_children
# File 'lib/rexml/element.rb', line 1478
def texts find_all { |child| child.kind_of? Text }.freeze end
#whitespace
Returns true
if whitespace is respected for this element, false
otherwise.
See
.Element
Context
The evaluation is tested against the element’s expanded_name
, and so is namespace-sensitive.
# File 'lib/rexml/element.rb', line 490
def whitespace @whitespace = nil if @context if @context[:respect_whitespace] @whitespace = (@context[:respect_whitespace] == :all or @context[:respect_whitespace].include? ) end @whitespace = false if (@context[:compress_whitespace] and (@context[:compress_whitespace] == :all or @context[:compress_whitespace].include? ) ) end @whitespace = true unless @whitespace == false @whitespace end
#write(output = $stdout, indent = -1,, transitive = false, ie_hack = false)
DEPRECATED
See Formatters
Writes out this element, and recursively, all children.
- output
-
output an object which supports ‘<< string’; this is where the
document will be written.
- indent
-
An integer. If -1, no indenting will be used; otherwise, the indentation will be this number of spaces, and children will be indented an additional amount. Defaults to -1
- transitive
-
If transitive is true and indent is >= 0, then the output will be pretty-printed in such a way that the added whitespace does not affect the parse tree of the document
- ie_hack
-
This hack inserts a space before the /> on empty tags to address a limitation of Internet Explorer. Defaults to false
out = ''
doc.write( out ) #-> doc is written to the string 'out'
doc.write( $stdout ) #-> doc written to the console
# File 'lib/rexml/element.rb', line 1504
def write(output=$stdout, indent=-1, transitive=false, ie_hack=false) Kernel.warn("#{self.class.name}.write is deprecated. See REXML::Formatters", uplevel: 1) formatter = if indent > -1 if transitive require_relative "formatters/transitive" REXML::Formatters::Transitive.new( indent, ie_hack ) else REXML::Formatters::Pretty.new( indent, ie_hack ) end else REXML::Formatters::Default.new( ie_hack ) end formatter.write( self, output ) end
#xpath ⇒ string_xpath
Returns the string xpath to the element relative to the most distant parent:
d = REXML::Document.new('<a><b><c/></b></a>')
a = d.root # => <a> ... </>
b = a[0] # => <b> ... </>
c = b[0] # => <c/>
d.xpath # => ""
a.xpath # => "/a"
b.xpath # => "/a/b"
c.xpath # => "/a/b/c"
If there is no parent, returns the expanded name of the element:
e = REXML::Element.new('foo')
e.xpath # => "foo"
# File 'lib/rexml/element.rb', line 1192
def xpath path_elements = [] cur = self path_elements << __to_xpath_helper( self ) while cur.parent cur = cur.parent path_elements << __to_xpath_helper( cur ) end return path_elements.reverse.join( "/" ) end