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



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/rexle.rb', line 131

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



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/rexle.rb', line 113

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)]
  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

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



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/rexle.rb', line 213

def pretty_print(nodes, indent='0')
  indent = indent.to_i

  return '' unless nodes

  nodes.select(){|x| x.is_a? Rexle::Element or (x.is_a? String and x.strip.length > 0)}
      .map.with_index do |x, i|

    if x.is_a? Rexle::Element then
      case x.name
        when '!-'
          "<!--%s-->" % x.value  
        when '!['    
          "<![CDATA[%s]]>" % x.value
        else
          #return ["<%s/>" % x.name] if x.value = ''
          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
        end
    elsif x.is_a? String then
      x.sub(/^[\n\s]+$/,'')
    end
  end

end

#processing_instructions(s = '') ⇒ Object



150
151
152
153
154
# File 'lib/rexle.rb', line 150

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

#scan_print(nodes) ⇒ Object



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

def scan_print(nodes)

  nodes.map do |x|

    if x.is_a? Rexle::Element then
      case x.name
        when '!-'
          "<!--%s-->" % x.value  
        when '!['    
          "<![CDATA[%s]]>" % x.value
        else

          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.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

            out = ["<%s>" % tag]
            #out << x.value unless x.value.nil? || x.value.empty?
            out << scan_print(x.children)
            out << "</%s>" % x.name
          else
            out = ["<%s/>" % tag]
          end
      end      
    elsif x.is_a? String then
      x
    end
  end

end

#scan_to_a(nodes) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/rexle.rb', line 193

def scan_to_a(nodes)

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

    if x.is_a? Rexle::Element then

      a = [x.name, x.value, x.attributes]
      (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