http://www.perlmonks.org?node_id=220406
Category: PerlMonks Related Scripts
Author/Contact Info /msh jeffa
Description: This little CGI script uses XML::LibXML and XML::LibXSLT to transform a node (fetched in XML display mode via LWP::Simple) from XML to HTML. This script is not necessarily meant to replace the print display mode, but instead as an example of how to use XSLT with Perl to transform XML to HTML.

The HTML::Entities module is used in the final step to decode the entities in the node content. More work could be done here like linking PM shortcuts ([id://], [cpan://], etc.), but since we already have a functioning print mode for nodes, why bother? :) This is simply here as a reference for further exploration. (it doesn't even work well on this type of node - Code Catecombs).

The XSL stylesheet is included in the DATA section, feel free to cut and paste it into it's own file.

UPDATE: added a default node per PodMaster's request.

#!/usr/bin/perl -T

use strict;
use warnings;
use CGI qw(:standard);
use LWP::Simple qw(get);
use HTML::Entities;
use XML::LibXML;
use XML::LibXSLT;

print header, start_html,
   start_form,
   textfield('node_id'), submit('ID'), 
   end_form, end_html,
;

my $id = param('node_id');
print hr, node2html($id);

sub node2html {
   my $id = shift || 181206;
   return qq(bad id "$id"\n) unless $id =~ /^\d+$/;

   my $xml  = get "http://perlmonks.org/index.pl?node_id=$id&displayty
+pe=xml";
   my $xslt = do {local $/; <DATA>};

   my $xml_parser  = XML::LibXML->new();
   my $xslt_parser = XML::LibXSLT->new();

   my $doc   = $xml_parser->parse_string($xml);
   my $style = $xml_parser->parse_string($xslt); 

   my $stylesheet = $xslt_parser->parse_stylesheet($style);
   my $results    = $stylesheet->transform($doc);

   return decode_entities($stylesheet->output_string($results));
}

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node">

<xsl:value-of select="./@title"/>
(<xsl:value-of select="./@id"/>)<br/>
by <xsl:value-of select="./author"/>
<hr/>
<blockquote>
<xsl:value-of select="./data/field"/>
</blockquote>

</xsl:template>
</xsl:stylesheet>
Replies are listed 'Best First'.
Re: Node XML to HTML
by particle (Vicar) on Dec 17, 2002 at 17:04 UTC

    ++! another neat-o trick from a master of xml

    one little thing: you might consider inverting the logic in your pattern match. i think it helps readability and maintainability a bit.

    ## turn (unless id contains one or more digits only) return qq(bad id "$id"\n) unless $id =~ /^\d+$/; ## into (if id contains non-digits) return qq(bad id "$id"\n) if $id =~ /\D/;

    ~Particle *accelerates*