title: Transform XML with multiple XSL files
body: <p>I have some XML that I'd like to transform into HTML using a number of XSL files. These XSL files are all related through xsl:import and xsl:include statements, and all required to complete the transform.</p>
  
  <p>I know the XSL works, because using the <code>&lt;?xml-stylesheet type="text/xsl" href="transform.xsl"?&gt;</code> directive in a pre-created XML file opened by the browser displays the output that I want. The problem is that I want to be able to replicate this functionality on dynamically generated XML.</p>
  
  <p>There are two ways that I can see that this can possibly be done, but both seem to have limitations that I have not been able to work around.</p>
  
  <p>The first solution is to use Javascript to transform the XML. From what I can tell, this will require the XSLTProcessor object to load multiple XSL files, but Chrome (and probably other browsers) don't support xsl:import very well - <a href="http://code.google.com/p/chromium/issues/detail?id=8441" rel="nofollow noreferrer">http://code.google.com/p/chromium/issues/detail?id=8441</a></p>
  
  <p>I also looked at writing the XML to an iFrame or new window, but the <code>&lt;?xml-stylesheet type="text/xsl" href="transform.xsl"?&gt;</code> directives are commented out in the resulting window. Actually anything written into a new window is HTML anyway - I have not found a way to write XML into a new window.</p>
  
  <p>So how can I get a browser window to display the result of an XML file transformed with a set of XSL files?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>So here is the results of my research into this problem.</p>
  
  <p><strong>Possible workaround</strong>: compile a tool like xsltproc into JavaScript using emscripten. I have actually done this - see <a href="https://github.com/mcasperson/xsltproc.js" rel="nofollow noreferrer">https://github.com/mcasperson/xsltproc.js</a></p>
  
  <p><strong>Problem</strong>: it is incredible slow in firefox (what takes 5 seconds in Chrome takes 30+ in firefox), and you can't run the code in a Chrome Web Worker - <a href="https://code.google.com/p/chromium/issues/detail?id=252492" rel="nofollow noreferrer">https://code.google.com/p/chromium/issues/detail?id=252492</a></p>
  
  <p><strong>Possible workaround</strong>: don't use XSL at all, but display the XML using CSS style sheets.</p>
  
  <p><strong>Problem</strong>: until browsers start implementing the <code>css attr(atrributename, url)</code> function, there is no way to treat a file reference in an XML attribute as anything other than a string, which makes it impossible to display images.</p>
  
  <p><strong>Possible workaround</strong>: Merge all the XSL files into a single style sheet</p>
  
  <p><strong>Problem</strong>: This is somewhat possible (see <a href="https://stackoverflow.com/questions/70143/merge-multiple-xslt-stylesheets">Merge multiple xslt stylesheets</a>), but xsl:import and xsl:include have particular semantics that don't carry across when simply substituting a files contents in place of a xsl:import or xsl:include statement. For large XSL transforms broken up over multiple files, this solution would require a lot of manual work.</p>
  
  <p><strong>Possible workaround</strong>: Write out the contents of the XML into an iframe or new window.</p>
  
  <p><strong>Problem</strong>: It is not possible to write XML into a new window or iframe. The contents written into these elements is always assumed to be HTML, and inserted into a HTML->BODY element.</p>
  
  <p><strong>Possible workaround</strong>: Create a server side service that takes XML and then returns that XML with the XSL stylesheet directive. The service URL can then be used as a <code>src</code> attribute for an iframe or new window.</p>
  
  <p><strong>Problem</strong>: The service would have to be a GET end point, which means the XML to be returned would have to be included as a query parameter, which means you'll eventually run into issues with the length of the URL.</p>
  
  <p><strong>Possible workaround</strong>: Use a javascript XSL library like <a href="http://www.saxonica.com/ce/doc/contents.html" rel="nofollow noreferrer">Saxonica CE</a>.</p>
  
  <p><strong>Problem</strong>: This may actually work (I haven't tried it), but Saxonica CE is no open source (which is a requirement of our project).</p>