mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-14 03:30:17 +01:00
274 lines
8.7 KiB
HTML
274 lines
8.7 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
|
|
<html>
|
|
<head>
|
|
<title>XSLT Templates and Compiling</title>
|
|
<style type="text/css">
|
|
.section {
|
|
background-color: #cfcfcf;
|
|
margin-left: 2em;
|
|
}
|
|
.required {
|
|
font-weight: bold;
|
|
}
|
|
.TODO {
|
|
color: red;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<h1>XSLT Templates and Compiling</h1>
|
|
<p>This document describes compiling of XSLT stylesheets and the
|
|
evaluation of the result.</p>
|
|
<div>
|
|
<ul>
|
|
<li><a href="#pre">Prerequisites</a></li>
|
|
<li><a href="#comp">Compilation</a></li>
|
|
<li><a href="#eval">Evaluation</a></li>
|
|
</ul>
|
|
</div>
|
|
<h2><a name="pre">Objectives:</a></h2>
|
|
<ul>
|
|
<li>Speed</li>
|
|
<li>Better support for AVTs</li>
|
|
<li>Interruptability of processing</li>
|
|
<li>exclude and alias namespaces</li>
|
|
</ul>
|
|
<h2>Concepts:</h2>
|
|
<div>
|
|
<dl>
|
|
<dt>LRE namespaces</dt>
|
|
<dd>All namespace aliases are merged wit import precedence
|
|
into an array of all namespace ids, which is used to map the
|
|
LRE namespace in the source to the LRE namespace in the
|
|
result. Non-aliased namespaces just have their namespace id
|
|
in that array.</dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<h2><a name="comp">Compilation:</a></h2>
|
|
<p>The XSLT specification describes XSLT in terms of the XPath
|
|
datamodel, something pretty close to a DOM. So we talk about the
|
|
input in terms of DOM elements.</p>
|
|
<div>The DOM nodes in a stylesheet get compiled into either
|
|
<ul>
|
|
<li>nothing :-) (stuff like xsl:output),</li>
|
|
<li><code>xslTopElement</code>s or</li>
|
|
<li><code>xslInstruction</code>s.</li>
|
|
</ul>
|
|
The <code>xslInstruction</code>s fall into classes,
|
|
<ol>
|
|
<li>simple instructions,</li>
|
|
<li>utilities (no-op, variable-pop, push-handler),</li>
|
|
<li>branching instructions,</li>
|
|
<li>instructions changing the result handler and</li>
|
|
<li>instructions calling into different
|
|
<code>xslTopElement</code>s.</li>
|
|
</ol>
|
|
</div>
|
|
<h2><a name="eval">How do instructions work?</a></h2>
|
|
<div>The general pattern used to create output from a set of
|
|
instructions is
|
|
<pre>while (instruction) {
|
|
rv = instruction.do(args);
|
|
if (NS_FAILED(rv)) {
|
|
//cleanup
|
|
return rv;
|
|
}
|
|
instruction = instruction.mNext;
|
|
}</pre>
|
|
This says pretty much all about simple and utility instructions.
|
|
</div>
|
|
<h3>Branching instructions</h3>
|
|
<div>see <a href="#choose">xsl:choose</a>. The trailing single
|
|
no-op helps in rejoining the paths, as that no-op can be created
|
|
before the paths and thus easily appended to each end of the
|
|
paths.</div>
|
|
<h3>Instructions that change the output handler</h3>
|
|
<div>These instructions (attribute, comment, pi creating text
|
|
handlers, variable possibly creating a rtf handler) get created
|
|
by inserting a push-handler-instruction into the workflow for
|
|
the start of the element and the XSLT instruction at the
|
|
end. The handler instruction should keep a non-owning reference
|
|
to the push-handler-instruction to get the result and restore
|
|
the previous handler.</div>
|
|
|
|
<h3><a name="apply-imports">xsl:apply-imports</a></h3>
|
|
<div class="section">no idea</div>
|
|
|
|
<h3><a name="apply-templates">xsl:apply-templates</a></h3>
|
|
<div class="section">
|
|
<dl>
|
|
<dt>members:</dt>
|
|
<dd>
|
|
<dl>
|
|
<dt>select</dt> <dd>node-set-expression</dd>
|
|
<dt>mode</dt> <dd>qname</dd>
|
|
<dt>sorts</dt> <dd>list of xsl:sort elements</dd>
|
|
<dt>params</dt> <dd>list of xsl:with-param elements</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>do()</dt>
|
|
<dd>set up the params, if any, evaluate the select, create a
|
|
evalContext and push it on the evalContextStack. push the next
|
|
instruction to the instruction return stack. trigger the new
|
|
context (how do we do this?).</dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<h3><a name="attribute">xsl:attribute</a></h3>
|
|
<div class="section">
|
|
<dl>
|
|
<dt>members:</dt>
|
|
<dd>
|
|
<dl>
|
|
<dt class="required">name</dt> <dd>AVT with QName value</dd>
|
|
<dt>namespace</dt> <dd>AVT with uri value</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>do()</dt>
|
|
<dd>the start tag pushes a textValueHandler, the end tag pops
|
|
the value handler and calls the outputhandler::attribute</dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<h3><a name="attribute-set">xsl:attribute-set</a> (tle)</h3>
|
|
<div class="section"><span class="TODO">attribute sets are merged,
|
|
we should pay attention that multiple stylesheet compilers
|
|
don't mix their content. Order of attributes is relevant, IMHO.</span>
|
|
<dl>
|
|
<dt>members:</dt>
|
|
<dd>
|
|
<dl>
|
|
<dt class="required">name</dt> <dd>qname</dd>
|
|
<dt>use-attribute-sets</dt> <dd>list of qnames</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>do()</dt>
|
|
<dd>merging and stuff needed in the global stylesheet object,
|
|
(NOT part of <a href="#import-frame">import frame).</a></dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<h3><a name="call-template">xsl:call-template</a></h3>
|
|
<div class="section">
|
|
<dl>
|
|
<dt>members:</dt>
|
|
<dd>
|
|
<dl>
|
|
<dt class="required">name</dt> <dd>qname</dd>
|
|
<dt>with-params</dt> <dd>list of xsl:with-params</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>do()</dt>
|
|
<dd>push the next instruction onto the instruction return
|
|
stack, lookup the template and set the instruction pointer
|
|
to the called template. Setup the params, if there are. This
|
|
does not change the evalContextStack.
|
|
<div class="issue">Can we cache this? What happens if a
|
|
added stylesheet between two transforms changes which
|
|
stylesheet this qname resolves to?</div></dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<h3><a name="choose">xsl:choose</a></h3>
|
|
<div class="section">
|
|
This is a branching instruction with one exit point and several
|
|
conditional entry points (xsl:when) and one default
|
|
(xsl:otherwise). The conditional entry points start with a
|
|
conditionalGotoInstrunction, which jumps to the next entry point
|
|
if they don't succeed. Each of them ends with a gotoInstruction
|
|
that jumps to the end of the xsl:choose (for simplicity in the
|
|
compilation phase, this might be a noopInstruction). The
|
|
xsl:otherwise is just the instructions list of the
|
|
xsl:otherwise, linked to the ending noopInstruction. Note that
|
|
this construct a single instruction list for the complete
|
|
xsl:choose, as the mNext of the final gotos is the next entry
|
|
point. This mNext is only used for iterations, though.
|
|
</div>
|
|
|
|
<h3><a name="comment">xsl:comment</a></h3>
|
|
<div class="section">
|
|
<dl>
|
|
<dt>do()</dt>
|
|
<dd>startElement pushes a textHandler, endElement takes the
|
|
value and calls ::comment() in the output handler</dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<h3><a name="copy">xsl:copy</a></h3>
|
|
<div class="section">
|
|
<dl>
|
|
<dt>members:</dt>
|
|
<dd></dd>
|
|
<dt>do()</dt>
|
|
<dd>xsl:copy has a <a
|
|
href="#attribute-sets">use-attribute-sets</a> attribute,
|
|
<span class="TODO">TODO</span></dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<h3><a name="copy-of">xsl:copy-of</a></h3>
|
|
<div class="section">
|
|
<dl>
|
|
<dt>members:</dt>
|
|
<dd>
|
|
<dl>
|
|
<dt class="required">select</dt>
|
|
<dd>an expression to be added to the result tree</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>do()</dt>
|
|
<dd>the value of the result is added to the result tree. If
|
|
the result is a RTF, the RTF is just fed into the output
|
|
handler, if the result is not a nodeset, it is converted
|
|
into a string and ::characters is called on the output
|
|
handler. For nodesets, the result is a list of source nodes
|
|
which have to be interpreted, for example thru the
|
|
stylesheet compiler. This has be xslt-blind, that is, xslt
|
|
elements in the source must be treated as LRE elements and
|
|
copied into the result, instead of generating XSLT
|
|
instructions. <span class="TODO">is this all?</span></dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<h3><a name="decimal-format">xsl:decimal-format</a> (tle)</h3>
|
|
<div class="section">xsl:decimal-format is stored in the global
|
|
stylesheet object, import precedence <b>does not</b> apply.</div>
|
|
|
|
<h3><a name="element">xsl:element</a></h3>
|
|
<div class="section">
|
|
<dl>
|
|
<dt>members:</dt>
|
|
<dd>
|
|
<dl>
|
|
<dt class="required">name</dt> <dd>AVT with QName
|
|
value</dd>
|
|
<dt>namespace</dt> <dd>AVT with URI value</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt>do()</dt>
|
|
<dd>xsl:element has <a
|
|
href="#attribute-sets">attribute-set</a>s, <span
|
|
class="TODO">todo</span>. Other than that, this just
|
|
generates an element. Note that the attributes of this
|
|
element have to be discarded, if the name AVT does not
|
|
evaluate to a QName.</dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<h3><a name="fallback">xsl:fallback</a></h3>
|
|
<div class="section"><span class="TODO">do we care?</span></div>
|
|
|
|
<h3><a name=""></a></h3>
|
|
<div class="section">
|
|
<dl>
|
|
<dt>members:</dt>
|
|
<dd></dd>
|
|
<dt>do()</dt>
|
|
<dd></dd>
|
|
</dl>
|
|
</div>
|
|
</body>
|
|
</html>
|