Module: XMLhelper

Included in:
Rexle, Rexle::Element
Defined in:
lib/rexle.rb

Overview

13-Oct-2014: feature: Implemented Rexle#clone 12-Oct-2014: feature: Implemented CSS style element selection 27-Sep-2014: bug fix: ELement values are now explicitly transformed to string 16-Sep-2014: Feature: Impelemented Rexle::Element#each_recursive 07-Aug-2014: feature: Rexle::CData can now be used to create CDATA 12-Jul-2014: XPath with a single element condition now works e.g. b 07-Jun-2014: bug fix: An XPath nested within an XPath (using a selector)

should now wok properly e.g. record/abc[item/xyz="red"]

04-Jun-2014: bug fix: If XPath contains /text(), only valid

text elements are returned

03-Jun-2014: bug fix: Text elements are now nil by default 01-Jun-2014: bug fix: XPath elements separated by a pipe ‘|’ are now

stripped of white space

20-May-2014: feature: XPath Descendants after the element (or without

the element) are now supported

02-Apr-2014: bug fix: Rexle::Element#each now returns the children,

including the 1st text element

24-Mar-2014: minor bug fix: A blank line is no longer inserted at the

top of the XML document

14-Mar-2014: bug fix: An XML processing instruction will now only be

display if declaration = true

12-Mar-2014: bug fix: Duplicate processing instruction bug fixed 17-Jan-2014: bug fix: Rexle::Element to_a now returns all child elements 31-Dec-2013: feature: now supports processing instructions 18-Dec-2013: feature fix: the result of text() is no longer unescaped 13-Dec-2013: bug fix: elements with dashes can now be queried 14-Nov-2013: feature: Implemented method content() to output XML as

unescaped plain text

08-Nov-2013: An element will now only be deleted if it has a parent 05-Nov-2013: If a node is added to the document which already exists in the

node, it will be moved accordingly.

05-Nov02013: XPath bug fix: recursive selector with conditional parent now

returns the correct child e.g. //b[2]/c

10-Oct-2013: bug fix: child elements which have the same name as their parent

are now select correctly through XPath

22-sep-2013: feature: remove() is now an alias of delete() 30-jul-2013: feature: Rexle::Element#xml now accepts an xpath 25-jun-2013: bug fix: doc.root.delete(xpath) fixed 10-Nov-2012: Elements can now be added starting from an empty document 06-Nov-2012: additional xpath predicate now implemented e.g.

fun/. > 200 => [false, false, true, true]

21-Oct-2012: xpath predicate now implemented e.g. fun/@id=‘4’ => true 20-Oct-2012: feature: added Rexle::Element#texts which is the equivalent

   of REXML::Element#texts
feature: Rexle::Element#add_text is now the equivalent of 
   REXML::Element#add_text

10-Sep-2012: bug fix: Removed code from method pretty_print in order to

get the XML displayed properly

23-Aug-2012: feature: implemented xpath function contains() 17-Aug-2012: bug fix: pretty print now ignores text containing empty space 16-Aug-2012: the current element’s text (if its not empty) is now returned

from its children method
15-Aug-2012: feature: xpath containing child

now supported

13-Aug-2012: bug fix: xpath can now handle the name() function 11-Aug-2012: bug fix: separated the max() method from 1 line into 3

and that fixed it

08-Aug-2012: feature: added Element#insert_before and Element#insert_after 19-Jul-2012: Changed children to elements where appropriate 15-Jul-2012: bug fix: self.root.value is no longer appended

to the body if there are no child elements

19-Jun-2012: a bug fix for .//*[@class] 17-Jun-2012: a couple of new xpath things are supported ‘.’ and ‘|’ 15-Apr-2012: bug fix: New element names are typecast as string 16-Mar-2012: bug fix: Element names which contain a colon can now be selected

in the xpath.

22-Feb-2012: bug resolution: Deactivated the PolyrexParser; using RexleParser instead 14-Jan-2012: Implemented Rexle::Elements#each 21-Dec-2011: Bug fix: xpath modified to allow querying from the actual root rather than the 1st child element from the root

Instance Method Summary collapse

Instance Method Details

#doc_pretty_print(children, declaration = true) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/rexle.rb', line 155

def doc_pretty_print(children, declaration=true)

  body = pretty_print(children,2).join

  a = self.root.attributes.to_a.map do |k,v| 
    "%s='%s'" % [k,(v.is_a?(Array) ? v.join(' ') : v)]
  end
  
  ind = "\n  "   
  xml = "<%s%s>%s%s%s</%s>" % [self.root.name, a.empty? ? '' : \
    ' ' + a.join(' '), ind, body, "\n", self.root.name]

  if self.instructions and declaration then
    processing_instructions("\n") + "\n" + xml
  else 
    xml
  end
end

#doc_print(children, declaration = true) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/rexle.rb', line 137

def doc_print(children, declaration=true)

  body = (children.nil? or children.empty? or children.is_an_empty_string? ) ? '' : scan_print(children).join

  a = self.root.attributes.to_a.map do |k,v|
    "%s='%s'" % [k,(v.is_a?(Array) ? v.join(' ') : v.to_s)]
  end

  xml = "<%s%s>%s</%s>" % [self.root.name, a.empty? ? '' : \
    ' ' + a.join(' '), body, self.root.name]

  if self.instructions and declaration then
    processing_instructions() + xml
  else 
    xml
  end
end

#inspectObject



174
175
176
# File 'lib/rexle.rb', line 174

def inspect()    
  "#<Rexle:%s>" % [self.object_id]
end

#pretty_print(nodes, indent = '0') ⇒ Object



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/rexle.rb', line 236

def pretty_print(nodes, indent='0')

  indent = indent.to_i
  return '' unless nodes

  nodes.select(){|x| x.to_s.strip.length > 0}
      .map.with_index do |x, i|

    if x.is_a? Rexle::Element then

      a = x.attributes.to_a.map do |k,v| 
        "%s='%s'" % [k,(v.is_a?(Array) ? v.join(' ') : v)]
      end
      a ||= []

      tag = x.name + (a.empty? ? '' : ' ' + a.join(' '))
      start = i > 0 ? ("\n" + '  ' * (indent - 1)) : ''          

      if (x.value and x.value.length > 0) \
          or (x.children and x.children.length > 0 \
          and not x.children.is_an_empty_string?) or x.name == 'script'  then

        ind1 = (x.children and x.children.grep(Rexle::Element).length > 0) ? 
          ("\n" + '  ' * indent) : ''
          
        out = ["%s<%s>%s" % [start, tag, ind1]]
        out << pretty_print(x.children, (indent + 1).to_s.clone) 
        ind2 = (ind1 and ind1.length > 0) ? ("\n" + '  ' * (indent - 1)) : ''
        out << "%s</%s>" % [ind2, x.name]            
      else

        out = ["%s<%s/>" % [start, tag]]
      end


    elsif x.is_a? String then  x.sub(/^[\n\s]+$/,'')
    elsif x.is_a? Rexle::CData then x.print        
    elsif x.is_a? Rexle::Comment then x.print           

    end
  end

end

#processing_instructions(s = '') ⇒ Object



178
179
180
181
182
# File 'lib/rexle.rb', line 178

def processing_instructions(s='')
  self.instructions.map do |instruction|
    "<?%s?>" % instruction.join(' ') 
  end.join s
end

#scan_print(nodes) ⇒ Object



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
213
# File 'lib/rexle.rb', line 184

def scan_print(nodes)

  nodes.map do |x|

    if x.is_a? Rexle::Element then

      a = x.attributes.to_a.map do |k,v| 
        "%s='%s'" % [k,(v.is_a?(Array) ? v.join(' ') : v)]
      end

      tag = x.name + (a.empty? ? '' : ' ' + a.join(' '))

      if  (x.children and x.children.length > 0 \
          and not x.children.is_an_empty_string?) or x.name == 'script' then

        out = ["<%s>" % tag]
        out << scan_print(x.children)
        out << "</%s>" % x.name
      else
        out = ["<%s/>" % tag]
      end
    
    elsif x.is_a? String then  x
    elsif x.is_a? Rexle::CData then x.print        
    elsif x.is_a? Rexle::Comment then x.print        
      
    end
  end

end

#scan_to_a(nodes) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/rexle.rb', line 215

def scan_to_a(nodes)

  nodes.inject([]) do |r,x|

    if x.is_a? Rexle::Element then

      a = [x.name, x.attributes, x.value]

      (a.concat(scan_to_a(x.children))) if x.children.length > 1
      r << a
    elsif x.is_a? String then

      r << x
    end

  end

end