This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Javascript Function with "<"


Hi Kobily,

> I had to use some javascript functions that involves
> for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;

OK. To understand how to do this, you have to learn to distinguish
between the *physical* document and the *logical* document.  In a
logical document, the above is the string:

  for(i=0;a&&i<a.length&&(x=a[1])&&x.oSrc;i++) x.src=x.oSrc;

However, there are certain characters that are special to XML,
especially '<' and '&'.  XML uses entities to escape them when it
writes a physical document: '<' is serialised as '&lt;' and '&' as
'&amp;' for example.  So *physically* the above string can be
represented in XML as:

  for(i=0;a&amp;&amp;i&lt;a.length&amp;&amp;(x=a[1])&amp;&amp;x.oSrc;i++) x.src=x.oSrc;

When an XML parser reads that, it creates the string that's above,
because it unescapes the relevant characters.  You could just as well
replace *every* character in that string with a character entity
reference, and it would make not one jot of difference to the XML
application using the string (e.g. XSLT processor, XML-aware browser).
For example, I could replace all the 'a' with their character entity
reference:

  for(i=0;&#x61;&amp;&amp;i&lt;&#x61;.length&amp;&amp;(x=&#x61;[1])&amp;&amp;x.oSrc;i++) x.src=x.oSrc;

Because escaping characters leads to long and unreadable XML, there's
a shorthand way of doing the same thing - using CDATA sections.
Within a CDATA section, all characters are treated just as characters.
So another XML version of the string is:

  <![CDATA[for(i=0;a&&i<a.length&&(x=a[1])&&x.oSrc;i++) x.src=x.oSrc;]]>

So what does this all mean for you?  Well, it's got two implications,
one for your XSLT stylesheet and one for the output that it produces.

Your XSLT stylesheet must be well-formed XML.  So all the special
characters have to be escaped within it, which you can do (as
discussed above) either with entities or with a CDATA section.  If
you're not dynamically generating the Javascript with XSLT, it's
probably worth using a CDATA section for comfort.  So, in your XSLT
stylesheet you need to have something like:

  <head>
     <script language="Javascript">
        <![CDATA[
          ...
          for(i=0;a&&i<a.length&&(x=a[1])&&x.oSrc;i++) x.src=x.oSrc;
          ...
        ]]>
     </script>
  </head>

You don't want to place it in a comment because comments in your XSLT
stylesheet won't be outputted into your result tree, and you want the
Javascript to show up in the result.

Since you are outputting HTML, I guess that you are using the 'html'
output method by setting:

  <xsl:output method="html" />

or by having an 'html' element as the top-most element in your result
tree?

If you are using the HTML output method, then the Javascript will be
outputted *unescaped* as:

  <head>
     <script language="Javascript">
          ...
          for(i=0;a&&i<a.length&&(x=a[1])&&x.oSrc;i++) x.src=x.oSrc;
          ...
     </script>
  </head>

This is because HTML accepts unescaped text content in script
elements.

If you are using the XML output method, perhaps because you're
producing XHTML, then the Javascript will be outputted *escaped*
because you're producing well-formed XML, as:

  <head>
     <script language="Javascript">
          ...
          for(i=0;a&amp;&amp;i&lt;a.length&amp;&amp;(x=a[1])&amp;&amp;x.oSrc;i++) x.src=x.oSrc;
          ...
     </script>
  </head>

If you want to make that more readable, you can tell the XSLT
processor that you want the script element to have as its content a
CDATA section, using:

  <xsl:output method="xml" cdata-section-elements="script" />

If you do this, a CDATA section will be automatically used within the
script element, so the output will be:
  
  <head>
     <script language="Javascript">
        <![CDATA[
          ...
          for(i=0;a&&i<a.length&&(x=a[1])&&x.oSrc;i++) x.src=x.oSrc;
          ...
        ]]>
     </script>
  </head>

Some people have suggested using disable-output-escaping. Disabling
output escaping is *hardly ever* necessary, and often dangerous
because it allows you to produce documents that aren't well-formed.
You should avoid it if you can, and you definitely can in this case.

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]