views:

101

answers:

2

So, I'm using the XSLT plugin for JQuery, and here's my code:

function AddPlotcardEventHandlers(){
    // some code
}

function reportError(exception){
    alert(exception.constructor.name + " Exception:  " + ((exception.name) ? exception.name : "[unknown name]") + " - " + exception.message);
}

function GetPlotcards(){
    $("#content").xslt("../xml/plotcards.xml","../xslt/plotcards.xsl", AddPlotcardEventHandlers,reportError);
}

Here's the modified jquery plugin. I say that its modified because I've added callbacks for success and error handling.

/*
 * jquery.xslt.js
 *
 * Copyright (c) 2005-2008 Johann Burkard (<mailto:[email protected]>)
 * <http://eaio.com&gt;
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 */

/**
 * jQuery client-side XSLT plugins.
 * 
 * @author <a href="mailto:[email protected]">Johann Burkard</a>
 * @version $Id: jquery.xslt.js,v 1.10 2008/08/29 21:34:24 Johann Exp $
 */
(function($) {
    $.fn.xslt = function() {
        return this;
    }
    var str = /^\s*</;
    if (document.recalc) { // IE 5+
        $.fn.xslt = function(xml, xslt, onSuccess, onError) {

             try{

                var target = $(this);

                var change = function() {
                    try{
                        var c = 'complete';
                        if (xm.readyState == c && xs.readyState == c) {
                                window.setTimeout(function() {
                                    target.html(xm.transformNode(xs.XMLDocument));
                                    if (onSuccess) onSuccess();
                                }, 50);
                        }
                    }catch(exception){
                        if (onError) onError(exception);
                    }
                };

                var xm = document.createElement('xml');
                xm.onreadystatechange = change;
                xm[str.test(xml) ? "innerHTML" : "src"] = xml;

                var xs = document.createElement('xml');
                xs.onreadystatechange = change;
                xs[str.test(xslt) ? "innerHTML" : "src"] = xslt;

                $('body').append(xm).append(xs);
                return this;

            }catch(exception){
                if (onError) onError(exception);
            }
       };
    }
    else if (window.DOMParser != undefined && window.XMLHttpRequest != undefined && window.XSLTProcessor != undefined) { // Mozilla 0.9.4+, Opera 9+
       var processor = new XSLTProcessor();
       var support = false;
       if ($.isFunction(processor.transformDocument)) {
           support = window.XMLSerializer != undefined;
       }
       else {
           support = true;
       }
       if (support) {
            $.fn.xslt = function(xml, xslt, onSuccess, onError) {

                try{

                    var target = $(this);
                    var transformed = false;

                    var xm = {
                        readyState: 4
                    };
                    var xs = {
                        readyState: 4
                    };

                    var change = function() {
                        try{
                             if (xm.readyState == 4 && xs.readyState == 4  && !transformed) {
                                var processor = new XSLTProcessor();
                                if ($.isFunction(processor.transformDocument)) {
                                    // obsolete Mozilla interface
                                    resultDoc = document.implementation.createDocument("", "", null);
                                    processor.transformDocument(xm.responseXML, xs.responseXML, resultDoc, null);
                                    target.html(new XMLSerializer().serializeToString(resultDoc));
                                }
                                else {
                                    processor.importStylesheet(xs.responseXML);
                                    resultDoc = processor.transformToFragment(xm.responseXML, document);
                                    target.empty().append(resultDoc);
                                }
                                transformed = true;
                                if (onSuccess) onSuccess();
                            }
                        }catch(exception){
                            if (onError) onError(exception);
                        }
                    };

                    if (str.test(xml)) {
                        xm.responseXML = new DOMParser().parseFromString(xml, "text/xml");
                    }
                    else {
                        xm = $.ajax({ dataType: "xml", url: xml});
                        xm.onreadystatechange = change;
                    }

                    if (str.test(xslt)) {
                        xs.responseXML = new DOMParser().parseFromString(xslt, "text/xml");
                        change();
                    }
                    else {
                        xs = $.ajax({ dataType: "xml", url: xslt});
                        xs.onreadystatechange = change;
                    }

                }catch(exception){
                    if (onError) onError(exception);
                }finally{
                    return this;
                }
            };
       }
    }
})(jQuery);

And, here's my error msg:

Object Exception: [unknown name] - Component returned failure code: 0x80600011 [nsIXSLTProcessorObsolete.transformDocument]

Here's the info on the browser that I'm using for testing (with firebug v1.5.4 add-on installed):

Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3

Here's my XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<plotcardCollection sortby="order">
    <plotcard order="2" id="1378">
        <name><![CDATA[[placeholder for name of plotcard 1378]]]></name>
        <content><![CDATA[[placeholder for content of plotcard 1378]]]></content>
        <tagCollection>
            <tag id="3"><![CDATA[[placeholder for tag with id=3]]]></tag>
            <tag id="7"><![CDATA[[placeholder for tag with id=7]]]></tag>
        </tagCollection>
    </plotcard>
    <plotcard order="1" id="2156">
        <name><![CDATA[[placeholder for name of plotcard 2156]]]></name>
        <content><![CDATA[[placeholder for content of plotcard 2156]]]></content>
        <tagCollection>
            <tag id="2"><![CDATA[[placeholder for tag with id=2]]]></tag>
            <tag id="9"><![CDATA[[placeholder for tag with id=9]]]></tag>
        </tagCollection>
    </plotcard>
</plotcardCollection>

Here's my XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:template match="/plotcardCollection">
    <xsl:variable name="sortby" select="@sortby" />
    <xsl:for-each select="plotcard">
      <xsl:sort select="$sortby" data-type="number" order="ascending"/>
      <div>

          <!-- Start Plotcard -->
          <xsl:attribute name="class">Plotcard</xsl:attribute>
          <xsl:for-each select="@">
              <xsl:value-of select="name()"/>
              <xsl:text>='</xsl:text>
              <xsl:if test="name() = 'id'">
                  <xsl:text>Plotcard-</xsl:text>
              </xsl:if>
              <xsl:value-of select="." />
              <xsl:text>'</xsl:text>
          </xsl:for-each>

          <!-- Start Plotcard Name Section -->
          <div>
              <xsl:attribute name="class">
                  <xsl:text disable-output-escaping="yes">PlotcardName</xsl:text>
              </xsl:attribute>
              <xsl:value-of select="name/text()"/>
          </div>

          <!-- Start Plotcard Content Section -->
          <div>
              <xsl:attribute name="class">
                  <xsl:text disable-output-escaping="yes">PlotcardContent</xsl:text>
              </xsl:attribute>
              <xsl:value-of select="content/text()"/>
          </div>
      </div>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

I'm really not sure what to do about this.... any thoughts?

A: 

First can you try adding a version number to the xslt file

e.g

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

Also I notice your using utf8 for the xslt and ISO-8859-1 for the xml. Long time since I used xml/xslt in any detail but could this cause issues?

redsquare
I've updated the XML to use UTF-8, and I've added the version number but neither seems to have resolved the issue.
Sean Ochoa
Shame, sorry without having this locally and being able to change things I cant see the issue. Hope someone else can!
redsquare
This is code from a web site I'm creating for my wife. I haven't made it publicly available, just yet.
Sean Ochoa
googling the error code brings up lots of things you could try!
redsquare
After a bunch of debugging, I've found that iterating through XML node attributes in XSLT, and adding attributes according to their names and values is what's causing it to fail. I'm trying to find a way around that limitation now.
Sean Ochoa
can you not use json and templates rather than xml/xslt. If you are stuck with xml/xslt I would rather do this at the server side, seen alot of pain with this client side + x-browser
redsquare
A: 

So, I figured this one out. Apparently I was referring to the attribute name variable incorrectly. The portion of XSLT that was failing was this:

          <xsl:for-each select="@">
              <xsl:value-of select="name()"/>
              <xsl:text>='</xsl:text>
              <xsl:if test="name() = 'id'">
                  <xsl:text>Plotcard-</xsl:text>
              </xsl:if>
              <xsl:value-of select="." />
              <xsl:text>'</xsl:text>
          </xsl:for-each>

And should be this:

      <xsl:for-each select="@*">
          <xsl:variable name="attrName">
              <xsl:value-of select="name()"/>
          </xsl:variable>
          <xsl:attribute name="{$attrName}">
            <xsl:if test="name() = 'id'">
                <xsl:text>Plotcard-</xsl:text>
            </xsl:if>
            <xsl:value-of select="."/>
          </xsl:attribute>
      </xsl:for-each>
Sean Ochoa