Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Print out an XML file to browser

by lakeTrout (Scribe)
on Feb 20, 2007 at 03:34 UTC ( [id://601014]=perlquestion: print w/replies, xml ) Need Help??

lakeTrout has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks

I built an XML parser from a flat file. From here, I woul like the XML file to print out in it's entirety to the browser (to verify it's well formed and eaiser to look at than text -- it can be it's own script because it will be part of a process/wizzard). Essentially, I just need a script that prints an XML file that already exists to a browser and nothing else. Am I making this harder than it has to be?

I'm thinking something like this, but I'm not sure if this is the right road to go down or if there isn't something better. Any help much appreciated!

#!/usr/bin/perl use strict; use warnings; use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); print header; print header, start_html ("XML File"), open(XMLFILE, "foo.xml"); while (<XMLFILE>){ print; }

Replies are listed 'Best First'.
Re: Print out an XML file to browser
by been42 (Curate) on Feb 20, 2007 at 04:10 UTC
    You should be able to just open foo.xml in your browser by clicking on the file. But if you'd like to output XML from your script to your browser and view it as XML, I think you need to change the Content-Type. I checked the CGI documentation, and it looks like this is how you'd do it:

    print start_html(-head=>meta({-http_equiv => 'Content-Type', -content => 'text/xml'}))

    Someone please correct me if I am wrong.

      Hi been42

      That is exactly what I am looking to do. I tried your start_html but it just returns a time stamp to the browser. Am I missing something more fundemental? I'm a bit of a CGI novie, but here is what I have so far:

      optput:Mon Feb 19 21:34:25 2007 processremote.cgi: readline() on closed filehandle XMLFILE at /my/upload/path/processremote.cgi line 15.

      #!/usr/bin/perl use strict; use warnings; use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); print header; print start_html(-head=>meta({-http_equiv => 'Content-Type', -content => 'text/xml'})); open(XMLFILE, "/my/upload/path/master.xml"); while (<XMLFILE>){ print $_; }
        Two things:
        1. If you know you want to output xml, then print header('text/xml'); is a lot simpler.
        2. Always check to see if your 'open' succeeded. Your error message means that your script didn't open the file.
        #!/usr/local/bin/perl use strict; use warnings; use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); print header('text/xml'); my $file = "/some/file.xml"; open(XMLFILE, $file) or die "Failed to open $file, $!"; while (<XMLFILE>){ print; }
        Please make sure whether you have "master.xml" in the specified location.
        Use the below code.
        open(XMLFILE, "/my/upload/path/master.xml") or die("Can't open file m +aster.xml : $!");
        also its best practice to close the filehandle after the usage.

      You need a real HTTP header, http-equiv is:

      • only applicable to HTML documents
      • can't specify content-type in a way that anything other than Russian Apache will care about

      The docs explain how to create standard http headers.

Re: Print out an XML file to browser
by odrm (Novice) on Feb 20, 2007 at 12:06 UTC

    Here are two options:

    1. send the xml to the browser, and let the browser render it:
      use CGI qw(:cgi); # don't need HTML, only cgi stuff
      print header(-type => 'application/xml');  # make browser expect xml
      open XML, '<', 'foo.xml' or die $!;
      print while <XML>;
    2. print an HTML rendering of your xml file:
      use CGI qw(:standard);
      sub escape_xml ($) {
        my $text = shift;
        $text =~ s/</&lt;/g;
        $text =~ s/ < >/&gt;/g;
        return $text;
      print header, start_html('XML File');
      open XML, '<', 'foo.xml' or die $!;
      print "<pre>\n";
      print escape_xml($_) while <XML>;
      print "\n</pre>";
    updated to fix the typo spotted by benizi (Thank you!)

      Nice. I like your coding style, odrm. But, it looks like you've got a copy-paste error in part 2. (s/</&gt;/g should be s/>/&gt;/g, yes?)

        Well spotted - yes it should be. I know why I prefer having perl do my escaping, over doing it by hand!
      Perfect! Thank you all, I have it working!
Re: Print out an XML file to browser
by almut (Canon) on Feb 20, 2007 at 11:04 UTC

    Which setup are you using, i.e. which webserver, browser...? In case you're using Firefox, there's a nifty little extension LiveHTTPHeaders that allows you to watch which HTTP headers are being exchanged between browser and webserver.

    If that doesn't help you to debug the "bad header" issue yourself, just post the respective headers that LiveHTTPHeaders (or some similar tool for your browser) is reporting.

    The print header('text/xml'); suggested by virtualsue works fine for me (using Apache / Firefox), so I suppose your problem is no longer related to the script code itself...

Re: Print out an XML file to browser
by Moron (Curate) on Feb 20, 2007 at 10:55 UTC
    The webserver is going to run this CGI script, so foo.xml should be in the default server directory. If it can't be (which is usually the case for maintainability reasons), you'll have to configure its location for the server and adjust the script as well. See your webserver documentation for info. on configuring file aliases, virtual hosts, etc.


    Free your mind

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://601014]
Approved by chargrill
Front-paged by csuhockey3
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-04-25 08:33 GMT
Find Nodes?
    Voting Booth?

    No recent polls found