Class: REXML::Elements

Inherits:
Object show all
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

Constructor Details

#initialize(parent) ⇒ Elements

Constructor

parent

the parent Element



770
771
772
# File 'lib/rexml/element.rb', line 770

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 +n+th element is at index n, not n-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 '' doc.root.elements #-> doc.root.elements #-> doc.root.elements #->



795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
# File 'lib/rexml/element.rb', line 795

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
		child = nil
		@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 '' doc.root.elements = Element.new('b') #-> doc.root.elements #-> doc.root.elements = Element.new('c') #-> doc.root.elements = Element.new('d') #->



828
829
830
831
832
833
834
835
836
# File 'lib/rexml/element.rb', line 828

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.elements.add 'c' #->



904
905
906
907
908
909
910
911
912
913
914
915
# File 'lib/rexml/element.rb', line 904

def add element=nil
	rv = 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, &block) ⇒ Object



937
938
939
940
941
942
943
# File 'lib/rexml/element.rb', line 937

def collect( xpath=nil, &block )
	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 '' b = doc.root.elements doc.root.elements.delete b #-> doc.elements.delete("a/c") #-> doc.root.elements.delete 1 #->



868
869
870
871
872
873
874
875
# File 'lib/rexml/element.rb', line 868

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 '' deleted = doc.elements.delete_all 'a/c' #-> [, , , ]



883
884
885
886
887
888
889
890
891
892
893
# File 'lib/rexml/element.rb', line 883

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, &block) ⇒ 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 'sean' doc.root.each {|e|p e} #-> Yields b, c, d, b, c, d elements doc.root.each('b') {|e|p e} #-> Yields b, b elements doc.root.each('child::node()') {|e|p e} #-> Yields , , , , , XPath.each(doc.root, 'child::node()', &block) #-> Yields , , , sean, , ,



933
934
935
# File 'lib/rexml/element.rb', line 933

def each( xpath=nil, &block)
	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

Returns:

  • (Boolean)


839
840
841
# File 'lib/rexml/element.rb', line 839

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



846
847
848
849
850
851
852
853
854
855
# File 'lib/rexml/element.rb', line 846

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, &block) ⇒ Object



945
946
947
948
949
950
951
952
953
954
955
956
957
958
# File 'lib/rexml/element.rb', line 945

def inject( xpath=nil, initial=nil, &block )
	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

#sizeObject

Returns the number of Element children of the parent object. doc = Document.new 'seanelliottrussell' doc.root.size #-> 6, 3 element and 3 text nodes doc.root.elements.size #-> 3



964
965
966
967
968
# File 'lib/rexml/element.rb', line 964

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 'seanelliott' doc.root.elements.to_a #-> [ , ] doc.root.elements.to_a("child::node()") #-> [ , ] XPath.match(doc.root, "child::node()") #-> [ sean, , elliott, ]



977
978
979
980
981
# File 'lib/rexml/element.rb', line 977

def to_a( xpath=nil )
	rv = XPath.match( @element, xpath )
	return rv.find_all{|e| e.kind_of? Element} if xpath
	rv
end