limc
limc

Reputation: 40168

Handling HTML tags in XSL

Before I explain the problem I'm facing, I probably need to explain the problem I wanted to solve in the first place. :)

I have an XML that will be formatted with XSL. This XML contains HTML tags in CDATA, for example:-

<doc>
    <![CDATA[
        <b>Hello!</b>
    ]]>
</doc>

When XSL performs the transformation, the browser displays <b>Hello!</b> rather than rendering the word Hello! in bold. I inspected the source code, and it looks like this:-

<doc>
    &lt;b&gt;Hello!&lt;/b&gt;
</doc>

To solve this problem, I'm thinking of using JQuery to render the text as HTML, like this:-

$(document).ready(function(){
    var obj = $(".content");
    alert("text: " + obj.text()); // to test if JQuery works
    obj.html(obj.text());
});

So, I tried adding the JQuery library into XSL, and after couple of attempts and reading about the problem with <script> tag, it seems like I need to add a dummy between the opening and closing <script> tag, like this:-

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js">
    <xsl:comment/>
</script>

The rendered display shows 2 errors in Firebug:-

b.style is undefined
(function(a,b){function ci(a){return d...a:a+"px")}}),a.jQuery=a.$=d})(window);

$ is not defined

... and the javascript statements above doesn't work at all, not even the alert prompt.

I decided to downgrade JQuery from 1.5.2 to 1.3.2 to see if that fixes anything. Now, I'm getting this error from Firebug:-

K.style is undefined
(function(){var R=/((?:\((?:\([^()]+\)...,typeof K==="string"?K:K+"px")}})})();

The good news is I'm getting the alert prompt with JQuery 1.3.2. The bad news is obj.html(obj.text()); doesn't do anything.

Just out of curiosity, I change obj.html(obj.text()); to obj.text("Just Testing: " + obj.text());, which is a dumb test, but it works... I'm seeing Just Testing: being inserted into the actual content.

How do I get obj.html(obj.text()); to work here? Or a more general question is, how do I get the HTML tags from CData to render as HTML and not as text?

Thanks much.

UPDATE

I did another test... obj.html("aaa"); doesn't work either. I'm starting to believe it has something to do with the XSL transformation that prevents JQuery from working properly. I'm still using 1.3.2 here.

Upvotes: 3

Views: 1736

Answers (3)

limc
limc

Reputation: 40168

After futzing around, I think I finally found a solution to my problem. I decided not to use JQuery because the Firebug errors really bug me.

I incorporated this getElementsByClassName() function from How to getElementByClass instead of GetElementById with Javascript? into my solution. I created my own JS called "xml.js":-

xml.js

function getElementsByClassName(node,classname) {
    if (node.getElementsByClassName) { // use native implementation if available
        return node.getElementsByClassName(classname);
    } 
    else {
        return (function getElementsByClass(searchClass,node) {
            if (node == null) {
                node = document;
            }
            var classElements = [],
            els = node.getElementsByTagName("*"),
            elsLen = els.length,
            pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"), i, j;

            for (i = 0, j = 0; i < elsLen; i++) {
                if ( pattern.test(els[i].className) ) {
                    classElements[j] = els[i];
                    j++;
                }
            }
            return classElements;
        })(classname, node);
    }
}

window.onload=function() {
    var elements = getElementsByClassName(document, "html");

    for (var i = 0; i < elements.length; i++) {
         var e = elements[i];
         e.innerHTML = e.innerHTML.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
    }
};

XSL

I added this JS reference in the XSL:-

<script type="text/javascript" src="xml.js"><xsl:comment/></script>

I basically added class="html" on the tags that require HTML formatting, for example:-

<p class="html">
    <xsl:call-template name="getDoc" />
</p>

XML

My XML has bunch of markups:-

<doc>     
  <![CDATA[         
     <b>Hello!</b> this is a <i>test</i>. 
      Email me at <a href="mailto:[email protected]">Moo</a>.
    ]]> 
</doc> 

The HTML within the CDATA seems to get rendered properly in the browser.

UPDATE

Just a side note, I also tried removing CDATA and escape < and >:-

<doc>     
     &lt;b&gt;Hello!&lt;/b&gt; this is a &lt;i&gt;test&lt;/i&gt;. 
      Email me at &lt;a href="mailto:[email protected]"&gt;Moo&lt;/a&gt;.
</doc> 

Then, I do the following:-

<xsl:value-of select="..." disable-output-escaping="yes" />

... and here's the result:-

  • IE 8: works, rendered correctly.
  • Chrome 9: works, rendered correctly
  • Safari 5: works, rendered correctly
  • Firefox 4: does not work - shows up tag instead of bolded word.

It seems like every browser is handling the rendering differently... pretty disappointed with FF4... bah.

At least for now, I'll stick with the javascript solution until I find a better one.

Upvotes: 1

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243469

Instead of :

<doc>     
  <![CDATA[         
     <b>Hello!</b>     
    ]]> 
</doc> 

Use:

<doc>     
  <b>Hello!</b>     
 </doc> 

Putting markup inside a CDATA section is effectively destroying this markup and converting it just to a string -- this is decreasing its dimension from 2 to 1.

Very bad practice that should ve avoided!

Upvotes: 3

theRedemer
theRedemer

Reputation: 7

Have you tried getting the text from obj first into a variable and then using the variable?

var objText = obj.text();
obj.html(objText);

Just a quick suggestion, just thought I would ask.

Upvotes: 0

Related Questions