class REXML::Element - rexml: Ruby Standard Library Documentation

# class REXML::Element

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}" }

Output:

    "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::Child`

- `REXML::Parent`

REXML::Element itself and its ancestors also include modules:

- Enumerable

- `REXML::Namespace`

- `REXML::Node`

- `REXML::XMLTokens`

### 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 `REXML::Elements` object for the element.

`attributes`

  Returns the `REXML::Attributes` object for the element.

`context`

  Returns or sets the context hash for the element.

### Constants

UNDEFINED

### Attributes

attributes[R]

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[R]

Mechanisms for accessing attributes and child elements of this element.

### Public Class Methods

new(name = 'UNDEFINED', parent = nil, context = nil) → new_element click to toggle source
new(element, parent = nil, context = nil) → new_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 `REXML::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}

Calls superclass method

    # File rexml-3.4.0/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.expanded_name
        arg.attributes.each_attribute{ |attribute|
          @attributes << Attribute.new( attribute )
        }
        @context = arg.context
      end
    end

### Public Instance Methods

[index] → object click to toggle source
[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

Output:

    "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

Calls superclass method

    # File rexml-3.4.0/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

add_attribute(name, value) → value click to toggle source
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 rexml-3.4.0/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 click to toggle source
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 rexml-3.4.0/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) → new_element click to toggle source
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 rexml-3.4.0/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 click to toggle source

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 rexml-3.4.0/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 click to toggle source
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"]

    # File rexml-3.4.0/lib/rexml/element.rb, line 1147
    def add_text( text )
      if text.kind_of? String
        if @children[-1].kind_of? Text
          @children[-1] << text
          return
        end
        text = Text.new( text, whitespace(), nil, raw() )
      end
      self << text unless text.nil?
      return self
    end

attribute(name, namespace = nil) click to toggle source

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 rexml-3.4.0/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 click to toggle source

Returns a frozen array of the `REXML::CData` children of the element:

    xml_string = <<-EOT
      <root>
        <![CDATA[foo]]>
        <![CDATA[bar]]>
      </root>
    EOT
    d = REXML::Document.new(xml_string)
    cds = d.root.cdatas      # => ["foo", "bar"]
    cds.frozen?              # => true
    cds.map {|cd| cd.class } # => [REXML::CData, REXML::CData]

    # File rexml-3.4.0/lib/rexml/element.rb, line 1420
    def cdatas
      find_all { |child| child.kind_of? CData }.freeze
    end

clone → new_element click to toggle source

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 rexml-3.4.0/lib/rexml/element.rb, line 383
    def clone
      self.class.new self
    end

comments → array_of_comment_children click to toggle source

Returns a frozen array of the `REXML::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 rexml-3.4.0/lib/rexml/element.rb, line 1441
    def comments
      find_all { |child| child.kind_of? Comment }.freeze
    end

delete_attribute(name) → removed_attribute or nil click to toggle source

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 rexml-3.4.0/lib/rexml/element.rb, line 1395
    def delete_attribute(key)
      attr = @attributes.get_attribute(key)
      attr.remove unless attr.nil?
    end

delete_element(index) → removed_element or nil click to toggle source
delete_element(element) → removed_element or nil
delete_element(xpath) → removed_element or nil

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 rexml-3.4.0/lib/rexml/element.rb, line 778
    def delete_element element
      @elements.delete element
    end

delete_namespace(namespace = 'xmlns') → self click to toggle source

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/>"

    # File rexml-3.4.0/lib/rexml/element.rb, line 687
    def delete_namespace namespace="xmlns"
      namespace = "xmlns:#{namespace}" unless namespace == 'xmlns'
      attribute = attributes.get_attribute(namespace)
      attribute.remove unless attribute.nil?
      self
    end

document → document or nil click to toggle source

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 rexml-3.4.0/lib/rexml/element.rb, line 475
    def document
      rt = root
      rt.parent if rt
    end

each_element {|e| ... } click to toggle source

Calls the given block with each child element:

    d = REXML::Document.new '<a><b>b</b><c>b</c><d>d</d><e/></a>'
    a = d.root
    a.each_element {|e| p e }

Output:

    <b> ... </>
    <c> ... </>
    <d> ... </>
    <e/>

    # File rexml-3.4.0/lib/rexml/element.rb, line 930
    def each_element( xpath=nil, &block ) # :yields: Element
      @elements.each( xpath, &block )
    end

each_element_with_attribute(attr_name, value = nil, max = 0, xpath = nil) {|e| ... } click to toggle source

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 }

Output:

    <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 }

Output:

    <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 }

Output:

    <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 }

Output:

    <d id='1'/>

    # File rexml-3.4.0/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| ... } click to toggle source

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 }

Output:

    <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 }

Output:

    <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 }

Output:

    <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 }

Output:

    <c> ... </>

    # File rexml-3.4.0/lib/rexml/element.rb, line 904
    def each_element_with_text( text=nil, max=0, name=nil, &block ) # :yields: Element
      each_with_something( proc {|child|
        if text.nil?
          child.has_text?
        else
          child.text == text
        end
      }, max, name, &block )
    end

get_elements(xpath) click to toggle source

Returns an array of the elements that match the given `xpath`:

    xml_string = <<-EOT
    <root>
      <a level='1'>
        <a level='2'/>
      </a>
    </root>
    EOT
    d = REXML::Document.new(xml_string)
    d.root.get_elements('//a') # => [<a level='1'> ... </>, <a level='2'/>]

    # File rexml-3.4.0/lib/rexml/element.rb, line 949
    def get_elements( xpath )
      @elements.to_a( xpath )
    end

get_text(xpath = nil) → text_node or nil click to toggle source

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 rexml-3.4.0/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

has_attributes? → true or false click to toggle source

Returns `true` if the element has attributes, `false` otherwise:

    d = REXML::Document.new('<root><a attr="val"/><b/></root>')
    a, b = *d.root
    a.has_attributes? # => true
    b.has_attributes? # => false

    # File rexml-3.4.0/lib/rexml/element.rb, line 1315
    def has_attributes?
      return !@attributes.empty?
    end

has_elements? click to toggle source

Returns `true` if the element has one or more element children, `false` otherwise:

    d = REXML::Document.new '<a><b/>text<c/></a>'
    a = d.root              # => <a> ... </>
    a.has_elements? # => true
    b = a[0]        # => <b/>
    b.has_elements? # => false

    # File rexml-3.4.0/lib/rexml/element.rb, line 794
    def has_elements?
      !@elements.empty?
    end

has_text? → true or false click to toggle source

Returns `true` if the element has one or more text noded, `false` otherwise:

    d = REXML::Document.new '<a><b/>text<c/></a>'
    a = d.root
    a.has_text? # => true
    b = a[0]
    b.has_text? # => false

    # File rexml-3.4.0/lib/rexml/element.rb, line 1002
    def has_text?
      not text().nil?
    end

ignore_whitespace_nodes click to toggle source

Returns `true` if whitespace nodes are ignored for the element.

See Element Context.

    # File rexml-3.4.0/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? expanded_name)
        end
      end
    end

inspect → string click to toggle source

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 rexml-3.4.0/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 click to toggle source

Returns a frozen array of the `REXML::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 rexml-3.4.0/lib/rexml/element.rb, line 1462
    def instructions
      find_all { |child| child.kind_of? Instruction }.freeze
    end

namespace(prefix = nil) → string_uri or nil click to toggle source

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 rexml-3.4.0/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 click to toggle source

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 rexml-3.4.0/lib/rexml/element.rb, line 591
    def namespaces
      namespaces = {}
      namespaces = parent.namespaces if parent
      namespaces = namespaces.merge( attributes.namespaces )
      return namespaces
    end

next_element click to toggle source

Returns the next sibling that is an element if it exists, `niL` otherwise:

    d = REXML::Document.new '<a><b/>text<c/></a>'
    d.root.elements['b'].next_element #-> <c/>
    d.root.elements['c'].next_element #-> nil

    # File rexml-3.4.0/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 click to toggle source

Returns symbol `:element`:

    d = REXML::Document.new('<a/>')
    a = d.root  # => <a/>
    a.node_type # => :element

    # File rexml-3.4.0/lib/rexml/element.rb, line 1168
    def node_type
      :element
    end

prefixes → array_of_namespace_prefixes click to toggle source

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 rexml-3.4.0/lib/rexml/element.rb, line 565
    def prefixes
      prefixes = []
      prefixes = parent.prefixes if parent
      prefixes |= attributes.prefixes
      return prefixes
    end

previous_element click to toggle source

Returns the previous sibling that is an element if it exists, `niL` otherwise:

    d = REXML::Document.new '<a><b/>text<c/></a>'
    d.root.elements['c'].previous_element #-> <b/>
    d.root.elements['b'].previous_element #-> nil

    # File rexml-3.4.0/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 click to toggle source

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 rexml-3.4.0/lib/rexml/element.rb, line 533
    def raw
      @raw = (@context and @context[:raw] and
              (@context[:raw] == :all or
               @context[:raw].include? expanded_name))
      @raw
    end

root → element click to toggle source

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`.

    # File rexml-3.4.0/lib/rexml/element.rb, line 443
    def root
      target = self
      while target
        return target.elements[1] if target.kind_of? Document
        parent = target.parent
        return target if parent.kind_of? Document or parent.nil?
        target = parent
      end
      nil
    end

root_node → document or element click to toggle source

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

Related: `root`, `document`.

    # File rexml-3.4.0/lib/rexml/element.rb, line 422
    def root_node
      parent.nil? ? self : parent.root_node
    end

text(xpath = nil) → text_string or nil click to toggle source

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 rexml-3.4.0/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 click to toggle source
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 rexml-3.4.0/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 click to toggle source

Returns a frozen array of the `REXML::Text` children of the element:

    xml_string = '<root><a/>text<b/>more<c/></root>'
    d = REXML::Document.new(xml_string)
    ts = d.root.texts
    ts.frozen?            # => true
    ts.map {|t| t.class } # => [REXML::Text, REXML::Text]
    ts.map {|t| t.to_s }  # => ["text", "more"]

    # File rexml-3.4.0/lib/rexml/element.rb, line 1478
    def texts
      find_all { |child| child.kind_of? Text }.freeze
    end

whitespace click to toggle source

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 rexml-3.4.0/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? expanded_name)
        end
        @whitespace = false if (@context[:compress_whitespace] and
                                (@context[:compress_whitespace] == :all or
                                 @context[:compress_whitespace].include? expanded_name)
                               )
      end
      @whitespace = true unless @whitespace == false
      @whitespace
    end

write(output=$stdout, indent=-1, transitive=false, ie_hack=false) click to toggle source

## DEPRECATED¶ ↑

See `REXML::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 rexml-3.4.0/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 click to toggle source

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 rexml-3.4.0/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

### Private Instance Methods

__to_xpath_helper(node) click to toggle source

    # File rexml-3.4.0/lib/rexml/element.rb, line 1521
    def __to_xpath_helper node
      rv = node.expanded_name.clone
      if node.parent
        results = node.parent.find_all {|n|
          n.kind_of?(REXML::Element) and n.expanded_name == node.expanded_name
        }
        if results.length > 1
          idx = results.index( node )
          rv << "[#{idx+1}]"
        end
      end
      rv
    end

each_with_something( test, max=0, name=nil ) { |child| ... } click to toggle source

A private helper method

    # File rexml-3.4.0/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