Class: REXML::Elements
- Includes:
- Enumerable
- Defined in:
- lib/rexml/element.rb
Overview
A class which provides filtering of children for Elements, and XPath search support. You are expected to only encounter this class as the element.elements
object. Therefore, you are not expected to instantiate this yourself.
Instance Method Summary collapse
-
#[](index, name = nil) ⇒ Object
Fetches a child element.
-
#[]=(index, element) ⇒ Object
Sets an element, replacing any previous matching element.
-
#add(element = nil) ⇒ Object
(also: #<<)
- Adds an element element
-
if supplied, is either an Element, String, or Source (see Element.initialize).
- #collect(xpath = nil) ⇒ Object
-
#delete(element) ⇒ Object
- Deletes a child Element element
-
Either an Element, which is removed directly; an xpath, where the first matching child is removed; or an Integer, where the n’th Element is removed.
-
#delete_all(xpath) ⇒ Object
Removes multiple elements.
-
#each(xpath = nil) ⇒ Object
- Iterates through all of the child Elements, optionally filtering them by a given XPath xpath
-
optional.
-
#empty? ⇒ Boolean
Returns
true
if there are noElement
children,false
otherwise. -
#index(element) ⇒ Object
- Returns the index of the supplied child (starting at 1), or -1 if the element is not a child element
-
an
Element
child.
-
#initialize(parent) ⇒ Elements
constructor
- Constructor parent
-
the parent Element.
- #inject(xpath = nil, initial = nil) ⇒ Object
-
#size ⇒ Object
Returns the number of
Element
children of the parent object. -
#to_a(xpath = nil) ⇒ Object
Returns an Array of Element children.
Constructor Details
#initialize(parent) ⇒ Elements
Constructor
- parent
-
the parent Element
765 766 767 |
# File 'lib/rexml/element.rb', line 765 def initialize parent @element = parent end |
Instance Method Details
#[](index, name = nil) ⇒ Object
Fetches a child element. Filters only Element children, regardless of the XPath match.
- index
-
the search parameter. This is either an Integer, which will be used to find the index’th child Element, or an XPath, which will be used to search for the Element. Because of the nature of XPath searches, any element in the connected XML document can be fetched through any other element. The Integer index is 1-based, not 0-based. This means that the first child element is at index 1, not 0, and the nth element is at index
n
, notn-1
. This is because XPath indexes element children starting from 1, not 0, and the indexes should be the same. - name
-
optional, and only used in the first argument is an Integer. In that case, the index’th child Element that has the supplied name will be returned. Note again that the indexes start at 1.
- Returns
-
the first matching Element, or nil if no child matched
doc = Document.new '<a><b/><c id="1"/><c id="2"/><d/></a>'
doc.root.elements[1] #-> <b/>
doc.root.elements['c'] #-> <c id="1"/>
doc.root.elements[2,'c'] #-> <c id="2"/>
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 |
# File 'lib/rexml/element.rb', line 790 def []( index, name=nil) if index.kind_of? Integer raise "index (#{index}) must be >= 1" if index < 1 name = literalize(name) if name num = 0 @element.find { |child| child.kind_of? Element and (name.nil? ? true : child.has_name?( name )) and (num += 1) == index } else return XPath::first( @element, index ) #{ |element| # return element if element.kind_of? Element #} #return nil end end |
#[]=(index, element) ⇒ Object
Sets an element, replacing any previous matching element. If no existing element is found ,the element is added.
- index
-
Used to find a matching element to replace. See []().
- element
-
The element to replace the existing element with the previous element
- Returns
-
nil if no previous element was found.
doc = Document.new '<a/>'
doc.root.elements[10] = Element.new('b') #-> <a><b/></a>
doc.root.elements[1] #-> <b/>
doc.root.elements[1] = Element.new('c') #-> <a><c/></a>
doc.root.elements['c'] = Element.new('d') #-> <a><d/></a>
822 823 824 825 826 827 828 829 830 |
# File 'lib/rexml/element.rb', line 822 def []=( index, element ) previous = self[index] if previous.nil? @element.add element else previous.replace_with element end return previous end |
#add(element = nil) ⇒ Object Also known as: <<
Adds an element
- element
-
if supplied, is either an Element, String, or Source (see Element.initialize). If not supplied or nil, a new, default Element will be constructed
- Returns
-
the added Element
a = Element.new('a')
a.elements.add(Element.new('b')) #-> <a><b/></a>
a.elements.add('c') #-> <a><b/><c/></a>
898 899 900 901 902 903 904 905 906 907 908 |
# File 'lib/rexml/element.rb', line 898 def add element=nil if element.nil? Element.new("", self, @element.context) elsif not element.kind_of?(Element) Element.new(element, self, @element.context) else @element << element element.context = @element.context element end end |
#collect(xpath = nil) ⇒ Object
930 931 932 933 934 935 936 |
# File 'lib/rexml/element.rb', line 930 def collect( xpath=nil ) collection = [] XPath::each( @element, xpath ) {|e| collection << yield(e) if e.kind_of?(Element) } collection end |
#delete(element) ⇒ Object
Deletes a child Element
- element
-
Either an Element, which is removed directly; an xpath, where the first matching child is removed; or an Integer, where the n’th Element is removed.
- Returns
-
the removed child
doc = Document.new '<a><b/><c/><c id="1"/></a>'
b = doc.root.elements[1]
doc.root.elements.delete b #-> <a><c/><c id="1"/></a>
doc.elements.delete("a/c[@id='1']") #-> <a><c/></a>
doc.root.elements.delete 1 #-> <a/>
862 863 864 865 866 867 868 869 |
# File 'lib/rexml/element.rb', line 862 def delete element if element.kind_of? Element @element.delete element else el = self[element] el.remove if el end end |
#delete_all(xpath) ⇒ Object
Removes multiple elements. Filters for Element children, regardless of XPath matching.
- xpath
-
all elements matching this String path are removed.
- Returns
-
an Array of Elements that have been removed
doc = Document.new '<a><c/><c/><c/><c/></a>'
deleted = doc.elements.delete_all 'a/c' #-> [<c/>, <c/>, <c/>, <c/>]
877 878 879 880 881 882 883 884 885 886 887 |
# File 'lib/rexml/element.rb', line 877 def delete_all( xpath ) rv = [] XPath::each( @element, xpath) {|element| rv << element if element.kind_of? Element } rv.each do |element| @element.delete element element.remove end return rv end |
#each(xpath = nil) ⇒ Object
Iterates through all of the child Elements, optionally filtering them by a given XPath
- xpath
-
optional. If supplied, this is a String XPath, and is used to filter the children, so that only matching children are yielded. Note that XPaths are automatically filtered for Elements, so that non-Element children will not be yielded
doc = Document.new '<a><b/><c/><d/>sean<b/><c/><d/></a>'
doc.root.elements.each {|e|p e} #-> Yields b, c, d, b, c, d elements
doc.root.elements.each('b') {|e|p e} #-> Yields b, b elements
doc.root.elements.each('child::node()') {|e|p e}
#-> Yields <b/>, <c/>, <d/>, <b/>, <c/>, <d/>
XPath.each(doc.root, 'child::node()', &block)
#-> Yields <b/>, <c/>, <d/>, sean, <b/>, <c/>, <d/>
926 927 928 |
# File 'lib/rexml/element.rb', line 926 def each( xpath=nil ) XPath::each( @element, xpath ) {|e| yield e if e.kind_of? Element } end |
#empty? ⇒ Boolean
Returns true
if there are no Element
children, false
otherwise
833 834 835 |
# File 'lib/rexml/element.rb', line 833 def empty? @element.find{ |child| child.kind_of? Element}.nil? end |
#index(element) ⇒ Object
Returns the index of the supplied child (starting at 1), or -1 if the element is not a child
- element
-
an
Element
child
840 841 842 843 844 845 846 847 848 849 |
# File 'lib/rexml/element.rb', line 840 def index element rv = 0 found = @element.find do |child| child.kind_of? Element and (rv += 1) and child == element end return rv if found == element return -1 end |
#inject(xpath = nil, initial = nil) ⇒ Object
938 939 940 941 942 943 944 945 946 947 948 949 950 951 |
# File 'lib/rexml/element.rb', line 938 def inject( xpath=nil, initial=nil ) first = true XPath::each( @element, xpath ) {|e| if (e.kind_of? Element) if (first and initial == nil) initial = e first = false else initial = yield( initial, e ) if e.kind_of? Element end end } initial end |
#size ⇒ Object
957 958 959 960 961 |
# File 'lib/rexml/element.rb', line 957 def size count = 0 @element.each {|child| count+=1 if child.kind_of? Element } count end |
#to_a(xpath = nil) ⇒ Object
Returns an Array of Element children. An XPath may be supplied to filter the children. Only Element children are returned, even if the supplied XPath matches non-Element children.
doc = Document.new '<a>sean<b/>elliott<c/></a>'
doc.root.elements.to_a #-> [ <b/>, <c/> ]
doc.root.elements.to_a("child::node()") #-> [ <b/>, <c/> ]
XPath.match(doc.root, "child::node()") #-> [ sean, <b/>, elliott, <c/> ]
970 971 972 973 974 |
# File 'lib/rexml/element.rb', line 970 def to_a( xpath=nil ) rv = XPath.match( @element, xpath ) return rv.find_all{|e| e.kind_of? Element} if xpath rv end |