http://www.perlmonks.org?node_id=109952
Category: HTML Utility
Author/Contact Info Briac 'OeufMayo' Pilpré
Description:

This is a small script that turns a valid XML file into a colorful HTML file! Yay!

Some handlers have not been used (most notably entities, notations), but they should be, eventually.

Update Tue Sep 4 07:46:13 UTC 2001: added mirod's suggestion. Thanks mirod!

#!/usr/bin/perl -w
use strict;
use XML::Parser;

my $parser = new XML::Parser(
    Handlers => {
        Init       => \&init,
        Start      => \&start,
        End        => \&end,
        Char       => \&char,
        Final      => \&final,
        Proc       => \&proc,
        Comment    => \&comment,
        CdataStart => \&cdstart,
        CdataEnd   => \&cdend,
        XMLDecl    => \&xmldecl,
        Doctype    => \&doctype,
    }
);

my $cdata;
my $style = <<'_CSS_';
.element {
    font-weight: bold;
    color: red;
}

.attrname {
    font-weight: bold;
    font-style: italic;
    color: green;
}

.attrvalue {
    font-style: italic;
    color: green;
}

.comment {
    color: blue;
}

.proc {
    color: green;
    font-weight: bold;
}

.cdata {
    color: violet;
}

.doctype {
    font-weight: bold;
    color: brown;
}


.xmldecl {
    font-weight: bold;
}

_CSS_

if( $ARGV[0]) { $parser->parsefile( $ARGV[0]); }
else          { $parser->parse( \*STDIN);      }

sub init  { print qq'<html><head><title></title><style type="text/css"
+>$style'
                  . '</style></head><body>' }
sub final { print '</body></html>' }

sub xmldecl {
    my ($p, $v, $e, $s) = @_;
    print qq'<p><span class="xmldecl">&lt;?xml version="$v" encoding="
+$e" '
        . qq'standalone="' .( $s ?  'yes' : 'no') . '"?&gt;</span></p>
+';
}

sub start {
    my ( $p, $e, %a ) = @_;
    print("<ul>");
    print(qq'&lt;<span class="element">$e</span>');
    foreach ( sort keys %a ) {
        print qq' <span class="attrname">$_=</span>'
            . qq'<span class="attrvalue">"$a{$_}"</span>';
    }
    print '&gt;';
}

sub end {
    my ( $p, $e ) = @_;
    print qq'&lt;/<span class="element">$e</span>&gt;';
    print '</ul>';
}

sub char {
    my ( $p, $s ) = @_;
    $s =~ s/\s+/ /g;

    if ($cdata){
        $s =~ s/&/&amp;/gs;
        $s =~ s/</&lt;/gs;
        $s =~ s/>/&gt;/gs;
        $s =~ s/"/&quot;/gs;
    }    
    print "$s";
}

sub proc {
    my ( $e, $t, $d ) = @_;
    print '<ul>';
    print qq'&lt;<span class="proc">?$t</b> $d<b>?</b>&gt;';
    print "</span></ul>";
}

sub comment {
    my ( $e, $d ) = @_;
    print '<ul><span class="comment">';
    print "&lt!-- $d --&gt;";
    print '</span></ul>';
}

sub cdstart { print '<ul>&lt;![CDATA[<span class="cdata">'; $cdata++ }
sub cdend   { print '</span>]]&gt;</ul>'; $cdata-- }

sub doctype {
    my ( $e, $n, $s, $p, $i ) = @_;
    print qq'<span class="doctype">';
    print qq'&lt;!DOCTYPE $n PUBLIC "$p" $i "$s" &gt;';
    print qq'</span>';

}
Replies are listed 'Best First'.
Re: XML Pretty Printer
by mirod (Canon) on Sep 04, 2001 at 11:09 UTC

    This looks very good!

    You could add the common idiom:

    if( $ARGV[0]) { $parser->parsefile( $ARGV[0]); } else { $parser->parse( \*STDIN); }

    to run the program either on STDIN or on the first argument

Re: XML Pretty Printer
by aufflick (Deacon) on Apr 26, 2006 at 02:29 UTC
    And yet again I could have saved myself time if I searched perlmonks before I searched google.

    Nice work.

    PS: The html comes out totally un-indented and deviod of newlines. I should update the script, but it's nothing that a few keystrokes in emacs couldn't fix ;)

      could you plkease tel me hoe to use thsi in .net environment thanks, ram
        Hi ram,

        This is Perl code. You can't run this code under .Net.

        There is, though, no reason why you can't run perl on your windows server as well as .Net. See http://perl.com/download.csp

Re: XML Pretty Printer
by gooch (Monk) on May 27, 2005 at 14:08 UTC
    This is really slick!
    Any idea how I could adapt this to run in a XML::SAX::PurePerl environment?
    Documentation on X::S::P is a bit on the spotty side to get this XML novice through an adaptation, and my environment has X::S::P but no C compiler, or I'd just install XML::Parser, and be done.
    :-) Any thoughts on this would be most helpful.
    Mike
Re: XML Pretty Printer
by Anonymous Monk on Jun 01, 2012 at 21:15 UTC
    Very nice; thanks for this. Nearly 11 years on and it works verbatim -- snarf'n'barf into xmlpretty.pl, chmod +x, and it Just Worked.

    My desktop is SuSE Linux 11.3 on a netvista, thinkcentre, or something like this.