forked from xmpp4r/xmpp4r
/
rexmladdons.rb
177 lines (152 loc) · 4.56 KB
/
rexmladdons.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# =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 <tt>e</tt> with text <tt>t</tt>.
def replace_element_text(e, t, namespace = nil)
el = first_element(e, namespace)
if el.nil?
el = REXML::Element.new(e)
el.add_namespace(namespace)
add_element(el)
end
if t
el.text = t
end
self
end
##
# Returns first element of name <tt>e</tt>
def first_element(e, namespace = nil)
if namespace
each_element_with_attribute("xmlns", namespace, 1, e) { |el| return el }
else
each_element(e) { |el| return el }
end
return nil
end
##
# Returns text of first element of name <tt>e</tt>
def first_element_text(e, namespace = nil)
el = first_element(e, namespace)
if el
return el.text
else
return nil
end
end
##
# This method works like <tt>first_element_text</tt> except that it
# returns content of all children, not just the value of the first
# child text element.
#
# Returns content of first element of name <tt>e</tt>
def first_element_content(e, namespace = nil)
el = first_element(e, namespace)
if el
return el.children.to_s
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