Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

XML::Generator bad header?

by hallikpapa (Scribe)
on Aug 19, 2007 at 00:16 UTC ( #633541=perlquestion: print w/replies, xml ) Need Help??
hallikpapa has asked for the wisdom of the Perl Monks concerning the following question:

I have this script that runs queries, and outputs it in XML format. Here is a snippet of what comes out if I print to screen:
<?xml version="1.0" encoding="ISO-8859-1"?> <dataset> <cdr> <id>08-15-2007.09 </id> <col2>202</col2> <col3>7</col3> <col4>7</col4> <col5>0</col5> <col6> 0.0</col6> <col7>100</col7> <col8> 1</col8> <col9> </col9> <col10>2007-08-15 09:57:56</col10> </cdr><cdr> <id>08-15-2007.09 </id> <col2>202</col2> <col3>8</col3> <col4>8</col4> <col5>0</col5> <col6>1414.5</col6> <col7>100</col7> <col8> 1</col8> <col9>10608</col9> <col10>2007-08-15 09:57:56</col10> </cdr><cdr> <id>08-15-2007.11 </id> <col2>240</col2> <col3>12</col3> <col4>12</col4> <col5>0</col5> <col6> 0.0</col6> <col7>100</col7> <col8> 2</col8> <col9> </col9> <col10>2007-08-15 11:57:15</col10> </cdr></dataset>
I am trying to push it back to the browser and I get this error in apache log
malformed header from script. Bad header=<?xml version="1.0" encoding= +":
This is how I print the header:
print "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"; print "<dataset>\n"; print @output; print "</dataset>";
I got that header from the website, so I am a bit confused on what the browser wants. Also, the file I wrote to looks exactly like the above data sample, but much larger, and the browser can't read it.

Replies are listed 'Best First'.
Re: XML::Generator bad header?
by ikegami (Pope) on Aug 19, 2007 at 00:26 UTC

    The problem is not with the XML header. (Apache doesn't care about what you are sending.) The problem is the non-adherence to the CGI specification, which requires a CGI header to be sent to STDOUT along with the body of the message to send to the HTTP client. Adding the following to your script will solve the problem:

    use CGI; print CGI->header('text/xml');
      I added what you suggested, here is the error I get when I try to load the XML file directly in the browser:
      XML Parsing Error: syntax error Location: http://localhost/now.xml Line Number 1, Column 1:Content-Type: text/xml ^
      I am looking for a specific CGI XML header way of printing a header. Below is what the raw xml file looks like now.
      Content-Type: text/xml^M ^M
      Trying this now
      print CGI->header('text/xml'); print "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
      <edit> This didn't work either.
      XML Parsing Error: syntax error Location: http://localhost/now.xml Line Number 1, Column 1:Content-Type: text/xml ^
      Content-Type: text/xml^M ^M <?xml version="1.0" encoding="ISO-8859-1"?>

        You are doing something wrong. Please show a little more piece of the code.

        Did you send any headers before

        print CGI->header('text/xml');

        You shouldn't be loading the file directly in the header with the Content-type: header as part of the file.

        The Content-type: header goes to STDOUT before any other output from your CGI program. It is followed by one blank line.

        After the Content-type: header is printed, your XML file's content can be sent to STDOUT from your CGI.

        The Content-type: header is never (or at least should never be) part of your actual XML file, so if you open the file directly in the browser, you should not have that as content.

        You can read more about the CGI specification at the NCSA, the W3C, or at the CGI section of CGI 1.1 co-author Ken Coar's web site, including info on issues with 1.1 and a draft for CGI 1.2 which may someday supersede it.
        OK, lets take a step back here, you are getting confused between what CGI is, and what the file is.

        This is what a CGI application should return TO THE WEB SERVER.

        -------------------------------------------------- Content-type: text/plain (or text/html and so on) Some-Other: headers (a blank line) The contents of the file goes here --------------------------------------------------

        So to send a text file the CGI prints this to STDOUT:

        -------------------------------------------------- Content-type: text/plain Hello World! --------------------------------------------------

        ... and a HTML file

        -------------------------------------------------- Content-type: text/html <html> <body> Hello World! </body> </html> --------------------------------------------------

        ... and an XML file

        -------------------------------------------------- Content-type: text/xml <?xml version="1.0" encoding="ISO-8859-1"?> <tag>Hello World!</tag> --------------------------------------------------

        I hope by now you see it's quite obvious you can't just spit the output of a CGI into a file and expect a browser to load that file, because you've incorrectly stuffed the extra headers into the file.

        It's no wonder the XML parser is freaking out.

        If you make a script that uses and adds the headers to the output, you can ONLY run it in a webserver.

        It's not useful for producing the file standalone any more.

        20070821 Janitored by Corion: Fixed stray </code> tag

        I ran into a bit of a problem with this recently too. This is what I had. It worked, but, with warnings on, it threw a warning about using an undefined value in a le comparison.

        use CGI; my $cgi = new CGI; #...more stuff not important to this discussion print $cgi->header( -type => 'application/xml'); print '<?xml version.......blah blah'."\n";

        My browser seemed to know what to do with it just fine.

        In order to get around the warning, I stopped using the cgi header method. This is now what I do.

        use CGI; my $cgi = new CGI; #...more stuff not important to this discussion print "Content-Type: application/xml\n". "\n". '<?xml version.......blah blah'."\n";

        I found that I had to have exactly two \n characters after the Content-Type, before the "<?xml" part. Any more or less and the browser complained about not being able to parse the xml even though applications looking at the xml could handle it.

Re: XML::Generator bad header?
by trs80 (Priest) on Aug 19, 2007 at 14:56 UTC
    Have you tried calling your script as .pl vs .xml ? It is possible that your webserver is attempting to send a header for you based on the mime type of the document (.xml extension )

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://633541]
Approved by ikegami
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2017-09-24 19:36 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (274 votes). Check out past polls.