xsl-list
[Top] [All Lists]

Re: [xsl] Troubles with libxslt in PHP again: CDATA in <script>

2007-10-13 04:15:09
Hi Abel,

well, on my machine I'm using PHP 5.2.2 which is giving me problems,
but my hosting uses 5.2.5 which seems to behave yet again differently.

My template contained JavaScript based on Google Maps API's "Hello world":
http://www.google.com/maps/api_signup?url=http%3A%2F%2Flocalhost

So it looked like this:

        <xsl:template name="map-js">
                <xsl:param name="zoom-level" select="0"/>
                <xsl:param name="set-coords" select="false()"/>
                <script type="text/javascript">
                        //<![CDATA[

                        function load()
                        {
                          if (GBrowserIsCompatible())
                          {
                                var map = new 
GMap2(document.getElementById("map"));

                                var children = []]><xsl:call-template 
name="js-children-array"/><![CDATA[];

                                map.setCenter(locationLatLng, ]]><xsl:value-of
select="$zoom-level"/><![CDATA[);

                                for (var i = 0; i < children.length; i++)
                                {
                                        var child = children[i];
                                        map.addOverlay(new GMarker(new 
GLatLng(child.lat, child.lng),
{title: child.name}));
                                }

                          }
                        }
                        //]]>
                </script>
        </xsl:template>

(I hope I didn't introduce errors by cutting out not so important stuff).
And what I get as output is:

        <script type="text/javascript"><![CDATA[
                //

                function load()
                {
                  if (GBrowserIsCompatible())
                  {
                        var map = new GMap2(document.getElementById("map"));

                        var children = [
                new Location("Denmark", 55.329144, 23.950195)];

                        var locationLatLng = new GLatLng(location.lat, 
location.lng);
                        map.setCenter(locationLatLng, 2);

                        for (var i = 0; i < children.length; i++)
                        {
                                var child = children[i];
                                map.addOverlay(new GMarker(new 
GLatLng(child.lat, child.lng),
{title: child.name}));
                        }                               
                  }
                }
                //
        ]]></script>

Notice how everything is wrapped in CDATA, so // comments are useless,
and browsers are giving JS errors because of CDATA (at least in the
"text/html" mode).
As I said, I think it is the same issue as in "Preventing CDATA output
in XHTML".

For now I switched to "html" output method as David suggested and all
is working fine.

Martynas

On 10/12/07, Abel Braaksma <abel(_dot_)online(_at_)xs4all(_dot_)nl> wrote:
Hi Martynas,

So you have libxslt (xsltproc) with php 5.2.5 and you get strange
results with CDATA sections wrapping the script tags. This struck me as
odd. I have got two questions for you:

   1. Can you post a minimalized sample and the precise version of
xsltproc you are using (see the list guidelines for how)?
   2. If you put the code that's in <script> inside another element, or
you just rename script to, say, script_other, does that still wrap the
scripts in CDATA?

The reason I am asking is because the libxslt behavior is quite
unlikely. You say you use the output option "xml". I tested the
following code both as XML and HTML. The difference showed in the way
the < and > are escaped in the script (with html they are not escaped).

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <html>
            <head>
                <title>test</title>
                <script>
                    function myfunc()
                    {
                        if(x>y) return 1;
                        if(x&lt;y) return 0;
                    }
                </script>
            </head>
            <body>
                <h1>Hello world</h1>
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>


It is a dummy example of course, but it showed the following output (no
cdata)  when run against libxslt 1.1.22, using libxml 2.6.30. These are
the current latest version as of today. I downloaded them here
http://www.zlatkovic.com/libxml.en.html (I can only test on windows),
but I don't believe they differ much from the originals. (you must set
method="xml" explicitly in this case, otherwise the processor recognizes
the html tag and automatically switches to html output format, but you
knew that already, of course :)

<?xml version="1.0"?>
<html>
  <head>
    <title>test</title>
    <script>
                    function myfunc()
                    {
                        if(x&gt;y) return 1;
                        if(x&lt;y) return 0;
                    }
                </script>
  </head>
  <body>
    <h1>Hello world</h1>
  </body>
</html>


Oh, and btw, it does not add content type "meta" for me. I do remember
the previous discussion, but I don't remember the conclusions. Are you
sure PHP, or the webserver, or some XML serializer (I know, you answered
Michael that you use the directly serialized string) is not adding
things? Can you check that by running the same code *without* the use
of  PHP? (something you should always check before attempting to solve
any weird issue that you blame on some specific tool or language).

HTH,
Cheers,
Abel Braaksma

Martynas Jusevicius wrote:
Hi xsl-list,

I'm working with PHP 5.2, and its XSL extension based on libxslt is
giving me headache again. It used to add Content-Type <meta> in my
XHTML output where it was not supposed to, and now in a similar manner
it is implicitly adding CDATA sections inside my <script> elements.

Most of the browsers do not understand CDATA in <script>, so that
gives JavaScript syntax error. Putting // comments to prevent that is
also not possible, since libxslt always puts CDATA before them.
Putting //<xsl:comment> to wrap my own CDATA used to do the trick, but
it does not work anymore with PHP 5.2.5 - libxslt wraps the leading //
in CDATA as well.

I think it is the same issue as in "Preventing CDATA output in XHTML":
http://www.biglist.com/lists/xsl-list/archives/200707/msg00060.html

I read that thread, but couldn't find any real solution that would fit
me. Upgrading libxslt is not an option, since it is built-in into PHP.
Can you think of any solutions or workarounds?

I'm using "xml" output method and XHTML 1.0 Strict doctype. I also
have to stick to "text/html" content type since Google Maps API (for
which I'm producing JavaScript) does not work properly with
"application/xhtml+xml".


Martynas Jusevicius
www.xml.lt

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--