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 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
module REXML
# If you add a method, keep in mind two things:
# (1) the first argument will always be a list of nodes from which to
# filter. In the case of context methods (such as position), the function
# should return an array with a value for each child in the array.
# (2) all method calls from XML will have "-" replaced with "_".
# Therefore, in XML, "local-name()" is identical (and actually becomes)
# "local_name()"
module Functions
@@node = nil
@@pair = []
@@variable = {}
def Functions::node=(value)
@@node = value
end
def Functions::pair=(value)
@@pair = value
end
def Functions::variable=(value)
@@variable = value
end
def Functions::node
@@node
end
def Functions::pair
@@pair
end
def Functions::variable
@@variable
end
def Functions::text( )
return true if @@node.kind_of? Text
end
def Functions::last( )
@@pair[1]
end
def Functions::position( )
@@pair[0]
end
def Functions::count( node_set )
node_set.size
end
# Since REXML is non-validating, this method is not implemented as it
# requires a DTD
def Functions::id( object )
end
# NOT TESTED
def Functions::local_name( node_set=nil )
get_namespace( node_set ){|node|node.local_name}
end
# NOT TESTED
def Functions::namespace_uri( node_set=nil )
get_namespace( node_set ) {|node| node.namespace}
end
def Functions::name( node_set=nil )
get_namespace( node_set ) { |node| node.name }
end
# Helper method.
def Functions::get_namespace( node_set = nil )
if node_set == nil
yield @@node if @@node.kind_of? Namespace
else
return "" unless node_set.kind_of? Enumerable
node = node_set.find{|node| node.kind_of? Namespace}
return "" unless node
yield node
end
end
# UNTESTED
def Functions::string( object=nil )
object = context unless object
if object.kind_of? Array
string( object[0] )
elsif object.kind_of? Text
object.to_s
elsif object.kind_of? Element
object.name
else
object.to_s
end
end
# UNTESTED
def Functions::concat( *objects )
objects.join
end
# UNTESTED
def Functions::starts_with( string, test )
string.index(test) == 0
end
# UNTESTED
def Functions::contains( string, test )
string.include? test
end
# UNTESTED
def Functions::substring_before( string, test )
string[ 0...string.index(test) ]
end
# UNTESTED
def Functions::substring_after( string, test )
string[ string.index(test)+1..-1 ]
end
# UNTESTED
def Functions::substring( string, start, length=0 )
length = string.size if length==0
string[start-1,length]
end
# UNTESTED
def Functions::string_length( string )
string.size
end
# UNTESTED
def Functions::normalize_space( string=nil )
string = string(@@node) if string.nil?
string.strip.gsub(/\s+/um, ' ')
end
# UNTESTED
def Functions::translate( string, tr1, tr2 )
string.tr tr1,tr2
end
# UNTESTED
def Functions::boolean( object=nil )
if object.kind_of? String
if object =~ /\d+/u
return object.to_f != 0
else
return object.size > 0
end
elsif object.kind_of? Array or object.kind_of? Parent
object.size > 0
end
end
# UNTESTED
def Functions::not( object )
return object == "true" if object.is_a? String
not object
end
# UNTESTED
def Functions::true( )
true
end
# UNTESTED
def Functions::false( )
false
end
# UNTESTED
def Functions::lang( language )
@@node.collect do |node|
if node.kind_of? Element
lang = false
until node.nil? or lang
lang = compare_language node.attributes["xml:lang"], language
node = node.parent
end
end
end
end
def Functions::compare_language lang1, lang2
lang2.downcase.index(lang1.downcase) == 0
end
def Functions::number( nodes, object=nil )
end
def Functions::sum( nodes )
end
def Functions::floor( nodes, number )
number = number.to_f if number.kind_of? String
number.floor
end
def Functions::ceiling( nodes, number )
number = number.to_f if number.kind_of? String
number.ceil
end
def Functions::round( nodes, number )
number = number.to_f if number.kind_of? String
number.round
end
def Functions::method_missing( id )
XPath.match( @@node, id.id2name )
end
end
end
|