Paul Bergström
Paul Bergström

Reputation: 253

Pass source xml file name as a parameter to the stylesheet

As I have understood it there is no way to get XSLT 1.0 in a stylesheet to accept direct funtions like "base-uri()" or simliar and I have read about a method when you "pass source xml file name as a parameter to the stylesheet".

What does that exactly mean?

My situation is that I have a large number of XML-files and one stylesheet that I would like to use for all of these files.

In the head section, when XSLT transformed, I would really like to display the source xml filename (i.e. the file that invoked the stylesheet).

How could this be done in the simplest way?

Many thanks!

/Paul

Upvotes: 0

Views: 1174

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

Assuming your XSLT transforms your XML input to HTML then in your HTML you can use Javascript to read out window.location.href respectively its components. The usual way to simply output something with client-side Javascript in a certain position would be document.write, but that is not supported in Gecko browsers in the HTML result of an XSLT transformation. You can however use DOM methods like createTextNode and replaceChild or appendChild, the following tries to do that and mimic the effect of document.write by replacing the script element with a text node:

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

<xsl:template match="/">
  <html>
    <head>
      <title>Test</title>
      <script>
      function outputUrl() {
      var currentScripts = document.getElementsByTagName('script');
        var lastScript = currentScripts[currentScripts.length - 1];
        var fileUrl = window.location.href;
        var steps = fileUrl.split('/');
        var fileName = steps[steps.length - 1];
        lastScript.parentNode.replaceChild(document.createTextNode(fileName), lastScript);
      }
      </script>
    </head>
    <body>
      <h1>Test</h1>
      <section>
        <h2>File : <script>outputUrl();</script></h2>
      </section>
      <xsl:apply-templates/>
    </body>
  </html>
</xsl:template>

<xsl:template match="footer">
  <section>
    <h2>Footer of file : <script>outputUrl();</script></h2>
  </section>
</xsl:template>

</xsl:stylesheet>

In an online test http://home.arcor.de/martin.honnen/xslt/test2015071502.xml with current versions of Firefox, Chrome and IE (on Windows 8.1) that way the file name show up in the right places but I have not tested that approach when more script elements are present with src attributes or defer or async. But you could always make sure you put a <span id="fileName"></span> where you need the file name and then use document.getElementById('fileName').textContent = fileName;, that way the output does not depend on the perhaps brittle approach of hoping that the document.getElementsByTagName('script') collection has the current script as it last item.

Upvotes: 1

Related Questions