Tuesday, November 30, 2010

rexml notes

REXML::Document.write is deprecated


rexml printing can be done with something like:
#!/usr/bin/env ruby
require 'rexml/document'
include REXML

doc = Document.new
doc << Element.new('root')
doc.elements['root'] << Element.new('child')

output = ''
doc.write output
puts output
#<root><child/></root>

output, indent = '', 1
doc.write output, indent
puts "with indent:"
puts output
=begin
with indent:
<root>
 <child/>
</root>
=end


new hotness


but that's deprecated. so use REXML::Formatters instead.

#!/usr/bin/env ruby
require 'rexml/document'
include REXML
doc = Document.new
doc << Element.new('root')
doc.elements['root'] << Element.new('child')

output, indent = '', 1
Formatters::Pretty.new(indent).write doc, output
puts output
=begin
<root>
 <child/>
</root>
=end


there are 2 other formatters availabe: default, and transitive. transitive does its best to preserve content nodes, including whitespace, but it will insert whitespace in non-content areas to improve formatting. so between attributes, tagnames, but not in text nodes.

more pretty print, please


pretty print also has a width, and a compact. compact will fit nodes with only text children onto 1 line if it can be done smaller than the width. large sections of text are always wrapped at 80 chars and indented 1 level further than their parent.
#!/usr/bin/env ruby
require 'rexml/document'
include REXML

doc = Document.new
doc << Element.new('root')
child = Element.new('child')
child << Text.new(<<-EOT)
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
EOT
small = Element.new('small')
small << Text.new(' little
text ')
doc.elements['root'] << child
doc.elements['root'] << small


output, indent = '', 20
pretty = Formatters::Pretty.new(indent)
pretty.width = 75
pretty.compact = true
pretty.write doc, output
puts output
=begin
<root>
<child>
Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit
in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim
id est laborum.
</child>
<small> little text </small>
</root>
=end


side note


i used this line for printing the above stuff escaping the characters, but preserving the whitespace:
File.open(__FILE__){ |f| puts Text.new(f.readlines.join, true) }

adding children on child creation


some child elements can have their parent node set on creation. works for Document, and Element nodes, but this doesn't work for text nodes, as far as i can tell.
#!/usr/bin/env ruby
require 'rexml/document'
include REXML

doc = Document.new
root = Element.new('root', doc)
child = Element.new('child', root)
Text.new('Lorem ipsum', child) #doesn't work, why?
small = Element.new('small', root)
little = Text.new(' little
text ')
small << little # adding text nodes like this works


output, indent = '', 20
pretty = Formatters::Pretty.new(indent)
pretty.width = 75
pretty.compact = true
pretty.write doc, output
puts output
=begin
<root>
<child/>
<small> little text </small>
</root>
=end

No comments:

Post a Comment

Where am I?