Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-2 of 2 total  RSS 

Pretty Print XML using Ruby

This code makes the XML output look pretty. I tried using the documentation from the REXML website to apply the method example doc.write($stdout,0), but I gave up, and instead wrote my own XML pretty-print method.

require 'rexml/document'
include REXML

  def pretty_print(parent_node, itab)
    buffer = ''

    parent_node.elements.each do |node|

      buffer += ' ' * itab + "<#{node.name}#{get_att_list(node)}"
  
      if node.to_a.length > 0
        buffer += ">"
        if node.text.nil?
          buffer += "\n"
          buffer += pretty_print(node,itab+2) 
          buffer += ' ' * itab + "</#{node.name}>\n"
        else
          node_text = node.text.strip
          if node_text != ''
            buffer += node_text 
            buffer += "</#{node.name}>\n"        
          else
            buffer += "\n" + pretty_print(node,itab+2) 
            buffer += ' ' * itab + "</#{node.name}>\n"        
          end
        end
      else
        buffer += "/>\n"
      end
      
    end
    buffer
  end

  def get_att_list(node)
    att_list = ''
    node.attributes.each { |attribute, val| att_list += " #{attribute}='#{val}'" }
    att_list
  end
  
  def pretty_xml(doc)
    buffer = ''
    xml_declaration = doc.to_s.match('<\?.*\?>').to_s
    buffer += "#{xml_declaration}\n" if not xml_declaration.nil?
    xml_doctype = doc.to_s.match('<\!.*\">').to_s
    buffer += "#{xml_doctype}\n" if not xml_doctype.nil?
    buffer += "<#{doc.root.name}#{get_att_list(doc.root)}"
    if doc.root.to_a.length > 0
      buffer +=">\n#{pretty_print(doc.root,2)}</#{doc.root.name}>"
    else
      buffer += "/>\n"
    end
  end

xml_data = "<hi id='124'><yo><a id='1'/><b/><c/></yo><sushi><love>Ruby</love></sushi></hi>"
doc = Document.new(xml_data)
pretty_xml(doc)


output
<hi id='124'>
  <yo>
    <a id='1'/>
    <b/>
    <c/>
  </yo>
  <sushi>
    <love>Ruby</love>
  </sushi>
</hi>


*Update 7-Jan-08 1:51AM *
Although I haven't tried running the following XSL code, this might actually have been a better solution to my problem. source: http://www.printk.net/~bds/indent.html

*Pretty Print XML using XSLT*
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="ISO-8859-1"/>
  <xsl:param name="indent-increment" select="'   '"/>
  
  <xsl:template name="newline">
    <xsl:text disable-output-escaping="yes">
</xsl:text>
  </xsl:template>
  
  <xsl:template match="comment() | processing-instruction()">
    <xsl:param name="indent" select="''"/>
    <xsl:call-template name="newline"/>    
    <xsl:value-of select="$indent"/>
    <xsl:copy />
  </xsl:template>
  
  <xsl:template match="text()">
    <xsl:param name="indent" select="''"/>
    <xsl:call-template name="newline"/>    
    <xsl:value-of select="$indent"/>
    <xsl:value-of select="normalize-space(.)"/>
  </xsl:template>
    
  <xsl:template match="text()[normalize-space(.)='']"/>
  
  <xsl:template match="*">
    <xsl:param name="indent" select="''"/>
    <xsl:call-template name="newline"/>    
    <xsl:value-of select="$indent"/>
      <xsl:choose>
       <xsl:when test="count(child::*) > 0">
        <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates select="*|text()">
           <xsl:with-param name="indent" select="concat ($indent, $indent-increment)"/>
         </xsl:apply-templates>
         <xsl:call-template name="newline"/>
         <xsl:value-of select="$indent"/>
        </xsl:copy>
       </xsl:when>       
       <xsl:otherwise>
        <xsl:copy-of select="."/>
       </xsl:otherwise>
     </xsl:choose>
  </xsl:template>    
</xsl:stylesheet>

XMLPrettyPrint: simple xml pretty print in perl

### begin_: file metadata
    ### <region-file_info>
    ### main:
    ###   - name    : XMLPrettyPrint: simple xml pretty print in perl
    ###     desc    : use perl with XML::Twig library to print indented xml
    ###     date    : created="Thu 2005-12-01 11:08:15"
    ###     last    : lastmod="Thu 2005-12-01 11:22:34"
    ###     lang    : perl
    ###     tags    : perl xml indent formatted pretty string cfPrettyPrint
    ### </region-file_info>

### begin_: init perl
    use strict;
    use warnings;
    use XML::Twig;

### begin_: init vars
    my  $sXML  = join "", (<DATA>);

    ### init params
    my  $params = [qw(none nsgmls nice indented record record_c)];
    my  $sPrettyFormat  = $params->[3] || 'none';

### begin_: process
    my  $twig= new XML::Twig;
    $twig->set_indent(" "x4);
    $twig->parse( $sXML );
    $twig->set_pretty_print( $sPrettyFormat );
    $sXML      = $twig->sprint;

### begin_: output
    print $sXML;

### begin_: sample data
    1;
    __END__
<table><tr age="35" >
<fname>Homer</fname>
<lname>Simpson</lname></tr>
<tr age="33" >
<fname>Barney</fname>
<lname>Rubble</lname></tr>
<tr age="29" >
<fname>Betty</fname>
<lname>Rubble</lname></tr></table>
« Newer Snippets
Older Snippets »
Showing 1-2 of 2 total  RSS