3

i have a tiny little problem with xslt, js and html entities, eg. within a template:

<script type="text/javascript">
    <xsl:value-of select="/some/node"/>
    for (var i = 0; i &lt; 5; i++) {
        //            ^^^ js error
    }
</script>

<script type="text/javascript">
    <xsl:value-of select="/some/node"/>
    for (var i = 0; i < 5; i++) {
        //            ^ xslt error
    }
</script>

<script type="text/javascript">
    <xsl:value-of select="/some/node"/>
    // <![CDATA[
    for (var i = 0; i < 5; i++) {
        //            ^ becomes &lt;
    }
    // ]]>
</script>


<script type="text/javascript">
    <xsl:value-of select="/some/node"/>
    for (var i = 0; i <xsl:value-of disable-output-escaping="yes" select="string('&lt;')"/> 5; i++) {
        // works of course
    }
</script>

does anyone have an idea where my problem could come from? i always thought the xslt processor would leave the content of a <script/> element unescaped when using the html output method ...

i run libxslt2 version 1.1.24 on OSX which was installed using macportsports ...

Eddie
  • 53,828
  • 22
  • 125
  • 145
Pierre Spring
  • 10,525
  • 13
  • 49
  • 44

5 Answers5

14

ok. long story, short answer:

it seems that with some libxslt versions the xslt processor leaves the content of a <script/> element unescaped when using the html output method, with others not ... therefore the following is recommended:

<script type="text/javascript">
    <xsl:value-of select="/some/node"/>
    <xsl:text disable-output-escaping="yes">
        // ^ does the trick ...
        for (var i = 0; i < 5; i++) {
            //            ^ works
        }
    </xsl:text>
</script>
Matthew Murdoch
  • 30,874
  • 30
  • 96
  • 127
Pierre Spring
  • 10,525
  • 13
  • 49
  • 44
  • HEY! You saved my life. No, at least a couple of hours! Thanks. – Marcos Buarque Mar 14 '09 at 19:56
  • Gidday there, this Question's a bit old now but if you get this, perhaps you can help with my Q? http://stackoverflow.com/questions/6411376/xslt-disable-output-escaping-not-holding-across-two-diff-servers Its the same problem, but your solution works on my localhost, but not my hosted server. They appear to have the same configuration :/ – danjah Jun 20 '11 at 12:57
  • 2
    This does not work in my case. I get the XSLT error `The content of elements must consist of well-formed character data or markup.` and it points to the line with the `<` – basZero Nov 12 '15 at 10:25
4

i always thought the xslt processor would leave the content of a script element unescaped when using the html output method

You are correct: http://www.w3.org/TR/xslt#section-HTML-Output-Method

The html output method should not perform escaping for the content of the script and style elements.
For example, a literal result element written in the stylesheet as
    <script>if (a &lt; b) foo()</script>
or
    <script><![CDATA[if (a < b) foo()]]></script>
should be output as
    <script>if (a < b) foo()</script>

If your XSLT processor is doing otherwise, it's a bug.

However, in any case it's a good idea to avoid '<' and '&' in embedded scripts, and an even better idea to kick all the code out into a linked .js file.

bobince
  • 528,062
  • 107
  • 651
  • 834
  • If XSLT is generating the variable JS script, a linked js file isn't always a possibility and avoiding < and & isn't going to be realistic – annakata Jan 12 '09 at 10:59
  • looks like a bug then ... i'll try to narrow it down the best i can an submit the bug report ... cheerz for your answer ... – Pierre Spring Jan 12 '09 at 11:17
1

The CDATA blocks should have worked; they always have for me. What's your disable-output-escaping value?

UPDATE: Using Xalan, with disable-output-escaping on its default, which I'm pretty sure is no, I have the following in my working XSL files:

  • No CDATA block:

    for (var i = 0; i `&lt;` foo.length; i++) {
    …
    }
    
  • CDATA block:

    <![CDATA[
    
    for (var i = 0; i < foo.length; i++) { … }
    
    ]]>
    
Jason Plank
  • 2,336
  • 5
  • 31
  • 40
Hank Gay
  • 70,339
  • 36
  • 160
  • 222
1

Try removing the double slash before the CDATA of your third solution

Olivier Payen
  • 15,198
  • 7
  • 41
  • 70
0

If the xsl:output method is html, the CDATA section would work. If the xsl:output method is xml, the < and > signs would still be converted.

To get around this problem, you may define the script element to not behave this way using the xsl:output element. you can also force the method of the output using xml or html

<xsl:output method="xml" cdata-section-elements="script" />
...
<script type="text/javascript" language="javascript">
<![CDATA[
  for (var i = 0; i &lt; foo.length; i++) { … }
]]>
</script>
Timofey Stolbov
  • 4,501
  • 3
  • 40
  • 45
  • This does not work in my case, what I get in the output is `&lt;`, and my output type is `html` – basZero Nov 12 '15 at 10:21