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
741 742 743 |
# File 'lib/rexml/element.rb', line 741 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"/>
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 |
# File 'lib/rexml/element.rb', line 766 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>
798 799 800 801 802 803 804 805 806 |
# File 'lib/rexml/element.rb', line 798 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>
874 875 876 877 878 879 880 881 882 883 884 |
# File 'lib/rexml/element.rb', line 874 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
906 907 908 909 910 911 912 |
# File 'lib/rexml/element.rb', line 906 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/>
838 839 840 841 842 843 844 845 |
# File 'lib/rexml/element.rb', line 838 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/>]
853 854 855 856 857 858 859 860 861 862 863 |
# File 'lib/rexml/element.rb', line 853 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/>
902 903 904 |
# File 'lib/rexml/element.rb', line 902 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
809 810 811 |
# File 'lib/rexml/element.rb', line 809 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
816 817 818 819 820 821 822 823 824 825 |
# File 'lib/rexml/element.rb', line 816 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
914 915 916 917 918 919 920 921 922 923 924 925 926 927 |
# File 'lib/rexml/element.rb', line 914 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
933 934 935 936 937 |
# File 'lib/rexml/element.rb', line 933 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/> ]
946 947 948 949 950 |
# File 'lib/rexml/element.rb', line 946 def to_a( xpath=nil ) rv = XPath.match( @element, xpath ) return rv.find_all{|e| e.kind_of? Element} if xpath rv end |