SitePoint Sponsor

User Tag List

Results 1 to 2 of 2
  1. #1
    SitePoint Member
    Join Date
    Jul 2011
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    transformToFragment on webkit browsers

    I just want to document a solution to a problem I was having with transformToFragment.

    I was having trouble with XSLTProcessor::transformToFragment() returning null on WebKit browsers (Safari and Chrome). Having read comments about issues with the load() method and xsl:import element, I used XMLHttpRequest and a very simple stylesheet and XML document for testing. Even after having eliminated the well-known problems, I was still disappointed to get a null return value from transformToFragment().

    Finally, I noticed that one example used:
    <xslutput method="html" />
    where I had been using:
    <xslutput method="xml" ... />

    When I changed my method to "html", the transformToFragment() worked.

    I hope this small bit of information will help someone.

  2. #2
    SitePoint Member
    Join Date
    Jul 2011
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Having fixed my first problem with transformToFragment, I discovered a second: the WebKit implementation of the function [Webkit-unassigned] [Bug 28744] XSLTProcessor transformToFragment mistakenly treats source node as root one

    In other words, the node you pass to transformToFragment is treated as a document element and thus causes your <xsl:template match="/"> to run.

    I can think of several ways this could defeat a stylesheet design if the stylesheet is used to process arbitrary document nodes for an XSL-driven web page.

    I offer this simple function to pre-process an XSL document prior to calling XSLTProcessor::importStylesheet, assuming that the contents of the document-matching template are not needed once the page has been rendered:

    Code:
    function fixWebKitStylesheet(doc)
    {
       // ensure output method = html:
       var node = doc.selectSingleNode("/xsl:stylesheet/xsl:output");
       if (node && node.getAttribute("method")=="xml")
          node.setAttribute("method", "html");
    
       // gut out document node template to deal with Webkit bug
       // Google: webkit bug 28744 "root one"
       if ((node=doc.selectSingleNode("/xsl:stylesheet/xsl:template[@match='/']")))
        {
          var child;
          while ((child=node.lastChild))
             node.removeChild(child);
          child = node.appendChild(doc.createElement("xsl:apply-templates"));
          child.setAttribute("select", "*");
       }
    }
    (Please forgive the extra conditional parens, emacs gripes if they're not used)
    and here is a sample if how that function might be called:

    Code:
    function getProcessor(doc)
    {
       // detect WebKit implementation (incomplete example pulled out
       // of other code that handles cross-browser XMLDOM differences):
       var d = document.implementation.createDocument("","",null);
       var isWebKit = !(d.load);
    
       var proc = new XSLTProcessor();
       if (isWebKit)
          fixWebKitStylesheet(doc);
    
       proc.importStylesheet(doc);
    
       return proc;
    }
    It's a relief to me that my XML-XSL methods can finally support Safari and now especially Chrome. The above code works for the ways I use transformToFragment, it may not work in every situation.

    I hope this helps someone.

    Chuck Jungmann


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •