# =XMPP4R - XMPP Library for Ruby
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
# Website::http://home.gna.org/xmpp4r/
require 'rexml/document'
require 'rexml/parsers/xpathparser'
require 'rexml/source'
# Turn $VERBOSE off to suppress warnings about redefinition
oldverbose = $VERBOSE
$VERBOSE = false
# REXML : Adds custom helper methods to the REXML module.
#
module REXML
# this class adds a few helper methods to REXML::Element
class Element
def each_elements(*els, &block)
els.inject([ ]) do |res, e|
res + each_element(e, &block)
end
end
##
# Replaces or adds a child element of name e with text t.
def replace_element_text(e, t)
el = first_element(e)
if el.nil?
el = REXML::Element.new(e)
add_element(el)
end
if t
el.text = t
end
self
end
##
# Returns first element of name e
def first_element(e)
each_element(e) { |el| return el }
return nil
end
##
# Returns text of first element of name e
def first_element_text(e)
el = first_element(e)
if el
return el.text
else
return nil
end
end
# This method does exactly the same thing as add(), but it can be
# overriden by subclasses to provide on-the-fly object creations.
# For example, if you import a REXML::Element of name 'plop', and you
# have a Plop class that subclasses REXML::Element, with typed_add you
# can get your REXML::Element to be "magically" converted to Plop.
def typed_add(e)
add(e)
end
##
# import this element's children and attributes
def import(xmlelement)
if @name and @name != xmlelement.name
raise "Trying to import an #{xmlelement.name} to a #{@name} !"
end
add_attributes(xmlelement.attributes.clone)
@context = xmlelement.context
xmlelement.each do |e|
if e.kind_of? REXML::Element
typed_add(e.deep_clone)
elsif e.kind_of? REXML::Text
add_text(e.value)
else
add(e.clone)
end
end
self
end
def self.import(xmlelement)
self.new(xmlelement.name).import(xmlelement)
end
##
# Deletes one or more children elements,
# not just one like REXML::Element#delete_element
def delete_elements(element)
while(delete_element(element)) do end
end
##
# Test for equality of two elements, useful for assert_equal in
# test cases. Tries to parse String o as XML.
#
# See Test::Unit::Assertions
def ==(o)
return false unless self.kind_of? REXML::Element
if o.kind_of? REXML::Element
# Ok
elsif o.kind_of? String
# Parse o
begin
o = REXML::Document.new(o).root
rescue REXML::ParseException
return false
end
else
# Cannot compare with anything other than Elements or Strings
return false
end
return false unless name == o.name
attributes.each_attribute do |attr|
return false unless attr.value == o.attributes[attr.name]
end
o.attributes.each_attribute do |attr|
return false unless attributes[attr.name] == attr.value
end
children.each_with_index do |child,i|
return false unless child == o.children[i]
end
return true
end
end # class Element
# FIXME : Is this still needed now that we're a bit past Ruby 1.8.3??
# Very dirty fix for the :progress problem in REXML from Ruby 1.8.3
# http://www.germane-software.com/projects/rexml/ticket/34
# the fix proposed in REXML changeset 1145 only fixes this for pipes, not for
# TCP sockets, so we have to keep this.
class IOSource
def position
0
end
def current_line
[0, 0, ""]
end
end # class IOSource
end # module REXML
# Restore the old $VERBOSE setting
$VERBOSE = oldverbose