in reply to XML tags using perl CGI

Read the up-to-date documentation:
-no_xhtml By default, CGI.pm versions 2.69 and higher emit XHTML (http://www +.w3.org/TR/xhtml1/). The -no_xhtml pragma disables this feature. Than +ks to Michalis Kabrianis <kabrianis@hellug.gr> for this feature. If start_html()'s -dtd parameter specifies an HTML 2.0 or 3.2 DTD, + XHTML will automatically be disabled without needing to use this pra +gma.

update: my CGI.pm does the correct thing for that code (slightly fixed so it can be run without editing):

use CGI; my $query = CGI->new; print $query->header(-type=>'text/html', -declare_xml=>0); print $query->start_html(-title=>'Blah blah blah.', -background=>"../images/$SiteName.background.jpg", -link=>'brown', -vlink=>'#8b4513', -style=>{'src'=>"$SiteName.styles.css"}, -script=>{ -language=>'JavaScript', -src=>"$SiteName.scripts.js" } );
output:
Declare-xml: 0 Content-Type: text/html; charset=ISO-8859-1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-U +S"> <head> <title>Blah blah blah.</title> <link rel="stylesheet" type="text/css" href=".styles.css" /> <script src=".scripts.js" type="text/javascript"></script> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1 +" /> </head> <body link="brown" vlink="#8b4513" background="../images/.background.j +pg">
Note that you actually should not use declare_xml as a parameter to header() but to start_html().

Replies are listed 'Best First'.
Re^2: XML tags using perl CGI
by pmcaveman (Novice) on Feb 06, 2007 at 11:43 UTC
    Great to hear it works for you -- I wonder what I am doing wrong. Boy, I wish it worked for me.
    I made some changes, with a minor bit of progress.
    #maybe the next two lines can be combined -- I am not sure use CGI::Carp qw(fatalsToBrowser); use CGI qw/:standard :html2/; #the standard also says if I set :html2, xhtml will go away (but it do +esn't seem to have an effect). #no idea how to set -dtd attributes my $query = CGI->new; print $query->start_html(-title=>'Argh!', -background=>"../images/$SiteName.background.jpg", -link=>'brown', -vlink=>'#8b4513', -no_xhtml=>1, #this has no effect... -dtd=>'3.2 DTD' #this does the trick, but not listed in the standa +rd as to how to set it -- I hope this is right... }
    And results:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">


    The worst part, is trying to validate the output using the w3c validator.

    Error Line 4 column 12: there is no attribute "XMLNS". <html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-U +S"><head> You have used the attribute named above in your document, but the docu +ment type you are using does not support that attribute for this elem +ent. This error is often caused by incorrect use of the "Strict" docu +ment type with a document that uses frames (e.g. you must use the "Tr +ansitional" document type to get the "target" attribute), or by using + vendor proprietary extensions such as "marginheight" (this is usuall +y fixed by using CSS to achieve the desired effect instead). This error may also result if the element itself is not supported in t +he document type you are using, as an undefined element will have no +supported attributes; in this case, see the element-undefined error m +essage for further information. How to fix: check the spelling and case of the element and attribute, +(Remember XHTML is all lower-case) and/or check that they are both al +lowed in the chosen document type, and/or use CSS instead of this att +ribute. Error Line 4 column 65: there is no attribute "XML:LANG". Error Line 7 column 93: document type does not allow element "META" he +re. The element named above was found in a context where it is not allowed +. This could mean that you have incorrectly nested elements -- such a +s a "style" element in the "body" section instead of inside "head" -- + or two elements that overlap (which is not allowed). One common cause for this error is the use of XHTML syntax in HTML doc +uments. Due to HTML's rules of implicitly closed elements, this error + can create cascading effects. For instance, using XHTML's "self-clos +ing" tags for "meta" and "link" in the "head" section of a HTML docum +ent may cause the parser to infer the end of the "head" section and t +he beginning of the "body" section (where "link" and "meta" are not a +llowed; hence the reported error).


    Anyway, I am confused. I wish this was a bit more straight-forward. I don't understand why things are being this difficult for me -- I just wanted a simple (and valid) html document header, not having to find and set all of these complicated flags everywhere to make the output simple.

    Thanks again for the help.
      the standard also says if I set :html2, xhtml will go away (but it doesn't seem to have an effect)

      Not sure which "standard" you're talking about there.

      The ':html2' import tag just defines the set of functions that are imported into your symbol table. As you're using the Object interface to CGI.pm it has no effect at all on your program.

      my $query = CGI->new; print $query->start_html(-title=>'Argh!', -background=>"../images/$SiteName.background.jpg", -link=>'brown', -vlink=>'#8b4513', -no_xhtml=>1, #this has no effect... -dtd=>'3.2 DTD' # this does the trick, but not listed in # the standard as to how to set it -- I # hope this is right... }

      Ah, you seem to be using "standard" to mean "the CGI.pm documentation", which is slightly unusual :-)

      The docs say:

      If start_html()'s -dtd parameter specifies an HTML 2.0 or 3.2 DTD, XHTML will automatically be disabled without needing to use this pragma.

      I think that means that you can override the whole DTD with this parameter. You can't just give it a string like "3.2 DTD", you need to give it a complete valid HTML DTD.

      Also, you're using the -no_xhtml pragma wrong (which is why it has no effect). It's not a parameter to start_html() (and nowhere does the documentation imply that). It's in the list of pragmas - which are arguments you give in the "use CGI" statement.

      I think that what you want is something like this:

      use CGI '-no_xhtml'; my $c = CGI->new; print $c->start_html;

      Which produces:

      <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="en-US"><head><title>Untitled Document</title> </head> <body>

      And if I can just make one further comment. Embedding HTML markup in your code using the CGI.pm methods is a really nasty way to go about it. Your life will be much easier if you separate your HTML from your code using some kind of templating system (I recommend the Template Toolkit, but other options are available).

      Update: s/usual/unusual/ - thanks to Corion for pointing it out.

        Ok, that is good to know. I am not completely understanding what a pragma is -- I though that is a precompiler option -- same here, so it forces some flags into the interpreter for that module?

        Also, I am unsure how to format the following options:
        use CGI::Carp qw(fatalsToBrowser); use CGI qw/:standard :html2/; use CGI '-no_xhtml';
        So, when I use CG_:Carp, do I also need to 'use CGI', or is it redundant? Do I need one line, or two? How should I combine the quotes, slashes and other parameters?

        I am almost scared to ask what all of that means -- I am sure there is an ocean of documentation which describes it that I don't have time to read...

        Thanks for the help.

        -Kevin