Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rexml - pretty print with text inline and child tags indented

I'm building an xml doc with REXML, and want to output to text in a particular way. The doc is a list of CuePoint tags, and the ones that i've generated with Element.new and add_element are all mushed together into a single line like this: (stackoverflow has split them over two lines here but imagine the following is all on one line):

<CuePoint><Time>15359</Time><Type>event</Type><Name>inst_50</Name></CuePoint><CuePoint><Time>16359</Time><Type>event</Type><Name>inst_50</Name></CuePoint>

When i save them out to file, i want them to look like this:

<CuePoint>
  <Time>15359</Time>
  <Type>event</Type>
  <Name>inst_50</Name>
</CuePoint>

<CuePoint>
  <Time>16359</Time>
  <Type>event</Type>
  <Name>inst_50</Name>
</CuePoint>

I tried passing the .write function a value of 2, to indent them: this produces the following:

xml.write($stdout, 2) produces

<CuePoint>
  <Time>
    15359
  </Time>
  <Type>
    event
  </Type>
  <Name>
    inst_50
  </Name>
</CuePoint>
<CuePoint>
  <Time>
    16359
  </Time>
  <Type>
    event
  </Type>
  <Name>
    inst_50
  </Name>
</CuePoint>

This is unwanted because it has inserted whitespace into the contents of the tags which just have text. ie the contents of the Name tag is now "\n inst_50\n " or something. This is going to blow up the app that reads the xml.

Does anyone know how i can format the output file the way i want it?

Grateful for any advice, max

EDIT - I just found the answer on ruby-forum, via another StackOverflow post: http://www.ruby-forum.com/topic/195353

  formatter = REXML::Formatters::Pretty.new
  formatter.compact = true
  File.open(@xml_file,"w"){|file| file.puts formatter.write(xml.root,"")}

This produces results like

<CuePoint>
  <Time>33997</Time>
  <Type>event</Type>
  <Name>inst_45_off</Name>
</CuePoint>
<CuePoint>
  <Time>34080</Time>
  <Type>event</Type>
  <Name>inst_45</Name>
</CuePoint>

There's no extra line between the CuePoint tags but that's fine for me. I'm leaving this question up here in case anyone else stumbles across it.

like image 350
Max Williams Avatar asked Jan 19 '11 16:01

Max Williams


1 Answers

You need to set the formatter's compact property to true, but you can only do that by setting a separate formatter object first, then using that to do your writing rather than calling the document's own write method.

formatter = REXML::Formatters::Pretty.new(2)
formatter.compact = true # This is the magic line that does what you need!
formatter.write(xml, $stdout)
like image 119
Dylan Markow Avatar answered Oct 22 '22 16:10

Dylan Markow