Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>Here is an example of multi-pass transformation within a browser</strong>:</p> <p><strong>Let us have this source XML document</strong>:</p> <pre><code>&lt;?xml-stylesheet title="XSL_formatting" type="text/xsl" href="MultiPassBrowser.xsl"?&gt; &lt;nums&gt; &lt;num&gt;01&lt;/num&gt; &lt;num&gt;02&lt;/num&gt; &lt;num&gt;03&lt;/num&gt; &lt;num&gt;04&lt;/num&gt; &lt;num&gt;05&lt;/num&gt; &lt;num&gt;06&lt;/num&gt; &lt;num&gt;07&lt;/num&gt; &lt;num&gt;08&lt;/num&gt; &lt;num&gt;09&lt;/num&gt; &lt;num&gt;10&lt;/num&gt; &lt;/nums&gt; </code></pre> <p><strong>Let us have these two XSLT transformations</strong>:</p> <h1>MultiPassBrowser1.xsl</h1> <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; &lt;xsl:output omit-xml-declaration="yes" indent="yes"/&gt; &lt;xsl:strip-space elements="*"/&gt; &lt;xsl:template match="node()|@*"&gt; &lt;xsl:copy&gt; &lt;xsl:apply-templates select="node()|@*"/&gt; &lt;/xsl:copy&gt; &lt;/xsl:template&gt; &lt;xsl:template match="num/text()"&gt; &lt;xsl:value-of select=". *2"/&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p>and</p> <h1>MultiPassBrowser2.xsl</h1> <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; &lt;xsl:output omit-xml-declaration="yes" indent="yes"/&gt; &lt;xsl:strip-space elements="*"/&gt; &lt;xsl:template match="node()|@*" mode="pass2"&gt; &lt;xsl:copy&gt; &lt;xsl:apply-templates select="node()|@*" mode="pass2"/&gt; &lt;/xsl:copy&gt; &lt;/xsl:template&gt; &lt;xsl:template match="num" mode="pass2"&gt; &lt;p&gt;&lt;xsl:value-of select=". +1"/&gt;&lt;/p&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p>The first transformation copies the XML document "as-is", but with the string value of every <code>num</code> element multiplied by 2.</p> <p>The second transformation copies the XML document "as-is", but with the string value of every <code>num</code> element incremented.</p> <p>If the second transformation is applied on the result of the first, the final values, obtained from the initial <code>num</code> elements must be 3, 5, 7, ..., 21.</p> <p><strong>Here is the transformation that glues these two together</strong>:</p> <h1>MultiPassBrowser.xsl</h1> <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="http://exslt.org/common" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="ext msxsl"&gt; &lt;xsl:import href="file:///C:/Temp/delete/MultiPassBrowser1.xsl"/&gt; &lt;xsl:import href="file:///C:/Temp/delete/MultiPassBrowser2.xsl"/&gt; &lt;xsl:output method="html"/&gt; &lt;xsl:strip-space elements="*"/&gt; &lt;msxsl:script language="JScript" implements-prefix="ext"&gt; this['node-set'] = function (x) { return x; } &lt;/msxsl:script&gt; &lt;xsl:template match="/"&gt; &lt;html&gt; &lt;xsl:variable name="vrtfPass1"&gt; &lt;xsl:apply-templates select="/*"/&gt; &lt;/xsl:variable&gt; &lt;xsl:apply-templates select="ext:node-set($vrtfPass1)/*/*" mode="pass2"/&gt; &lt;/html&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p><strong>The result, when the XML file is opened with both IE, Firefox, Safari and Opera, is the correct, expected one</strong>:</p> <pre><code>&lt;html&gt; &lt;p&gt;3&lt;/p&gt; &lt;p&gt;5&lt;/p&gt; &lt;p&gt;7&lt;/p&gt; &lt;p&gt;9&lt;/p&gt; &lt;p&gt;11&lt;/p&gt; &lt;p&gt;13&lt;/p&gt; &lt;p&gt;15&lt;/p&gt; &lt;p&gt;17&lt;/p&gt; &lt;p&gt;19&lt;/p&gt; &lt;p&gt;21&lt;/p&gt; &lt;/html&gt; </code></pre> <p><strong>Explanation</strong>:</p> <ol> <li><p>The primary stylesheet module (the one referenced in the XML document PI) imports the two stylesheet modules that contain the separate transformations.</p></li> <li><p>The result of the first transformation is captured in the variavle <code>$vrtfPass1</code>.</p></li> <li><p>In XSLT 1.0 such variable is of the infamous "RTF" (Result Tree Fragment) type and cannot be operated directly (only copying and the <code>string()</code> function can be used on an RTF). Here we use a portable variant of the <code>xxx:node-set()</code> extension function, that works both in IE and in the other four major browsers. <strong>This portable extension was first proposed by @DavidCarlisle and the original can be found in <a href="http://dpcarlisle.blogspot.com/2007_05_01_archive.html" rel="nofollow">his blog</a></strong>.</p></li> <li><p>Templates in mode "pass2" are then applied on the node-set, to which we converted, in the step above, the RTF variable. All templates in the second imported stylesheet module are in mode "pass2", thus they are selected for execution.</p></li> <li><p>The final result is produced.</p></li> </ol>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload