morten 02/01/06 08:34:53
Modified: java/xdocs/sources/xsltc index.xml
Added: java/xdocs/sources/xsltc xsl_choose_design.xml
xsl_if_design.xml xsl_include_design.xml
xsl_variable_design.xml xsltc_performance.xml
Log:
Added some new XSLTC design docs.
Submitted by: [EMAIL PROTECTED]
Revision Changes Path
1.11 +1 -1 xml-xalan/java/xdocs/sources/xsltc/index.xml
Index: index.xml
===================================================================
RCS file: /home/cvs/xml-xalan/java/xdocs/sources/xsltc/index.xml,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- index.xml 6 Jan 2002 15:52:00 -0000 1.10
+++ index.xml 6 Jan 2002 16:34:53 -0000 1.11
@@ -136,7 +136,7 @@
<li><link idref="xsl_variable_design"><xsl:param></link></li>
<li><link idref="xsl_include_design"><xsl:include></link></li>
<li><link idref="xsl_include_design"><xsl:import></link></li>
- <li><link
idref="xsl_apply_imp_design"><xsl:apply-imports></link></li>
+ <li><link
idref="xsl_imports_design"><xsl:apply-imports></link></li>
</ul>
</s4>
1.1 xml-xalan/java/xdocs/sources/xsltc/xsl_choose_design.xml
Index: xsl_choose_design.xml
===================================================================
<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
<!--
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Sun
* Microsystems., http://www.sun.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
-->
<s1 title="<xsl:choose> / <xsl:when> / <xsl:otherwise>">
<p><img src="xmllogo.gif"/></p>
<s2 title="Contents">
<ul>
<li><link anchor="functionality">Functionality</link></li>
<li><link anchor="implementation">Implementation</link></li>
</ul>
</s2>
<anchor name="functionality"/>
<s2 title="Functionality">
<p>The <code><xsl:choose></code> element is used to determine one
course of action based on a series of tests. Each test is done inside an
<code><xsl:when></code> element. If a test succeeds, the body of the
<code><xsl:when></code> element is executed. If no tests fail then
a <code><xsl:otherwise></code> element can be used to specify a
default action:</p>
<source>
<xsl:choose>
<xsl:when test="element-available('some-extension')">
...
</xsl:when>
<xsl:when test="function-availabe('saxon:nodeset')">
...
</xsl:when>
<xsl:otherwise>
...
</xsl:otherwise>
</xsl:choose></source>
</s2>
<anchor name="implementation"/>
<s2 title="Implementation">
<p>The <code>Choose</code> class places all <code>When</code> child-nodes
in a vector. The <code>Choose</code> class translates the "test"-attribute
of all <code>When</code> nodes (in strict order) and chains them together
in an if-else style. The expression that holds each test contains a true-
and a false-list. These lists are vectors of branch targets that should be
used if the test succeeds or fails, respectively. The first test's
false-list is pointed to the start of the next test (ie. if the first test
fails, then we run the next test). The last test's false-list points
directly
to the code for the body of the <code><xsl:otherwise></code> element.
</p>
<p>Just as with the <code><xsl:if></code>-element, special care is
taken for the <code>element-available()</code> and
<code>function-available()</code> functions. These functions are evaluated
at
compile-time (this can be done since all parameters for these functions are
literals) and the body of a <code><xsl:when></code> element is not
compiled if we know that it will never be needed at runtime.</p>
</s2>
</s1>
1.1 xml-xalan/java/xdocs/sources/xsltc/xsl_if_design.xml
Index: xsl_if_design.xml
===================================================================
<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
<!--
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Sun
* Microsystems., http://www.sun.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
-->
<s1 title="<xsl:if>">
<p><img src="xmllogo.gif"/></p>
<s2 title="Contents">
<ul>
<li><link anchor="functionality">Functionality</link></li>
<li><link anchor="implementation">Implementation</link></li>
</ul>
</s2>
<anchor name="functionality"/>
<s2 title="Functionality">
<p>This element is cruical to XSL processing, but still very simple both in
its use and implementation. The element is used like this:</p><source>
<xsl:if test="contains($the-world,'Elvis')">
<xsl:message>Elvis is still alive!</xsl:message>
</xsl:if></source>
<p>The element's contents will only be executed if the test succeeds. There
is no <code><xsl:else></code> element. One has to use either several
<code><xsl:if></code>-elements or use a choose-element.</p>
</s2>
<anchor name="implementation"/>
<s2 title="Implementation">
<p>The basic implementation is very simple:</p>
<ul>
<li>execute the expression from the 'test'-attribute</li>
<li>evaluate the resulting boolean value</li>
<li>ignore the element contents if the value is 'false'</li>
<li>otherwise execute the element contents</li>
</ul>
<p>There is onle type of function call that makes this a bit more
complicated.
The <code>function-available()</code> and <code>element-available()</code>
function calls can be used to test for extension elements and functions. A
very common use for these is to encapsulate all references to extension
elements inside an <code><xsl:if></code> element and test for the
existance of this element before attempting to use it. XSLTC has to support
this. Otherwise we may risk either outputting erronuous error or warning
messages about acessing non-existing elements, or even worse, compiling in
calls to non-existing methods in the translet, causing the JVM's verifier to
prevent the translet from being loaded.</p>
<p>The <code>function-available()</code> and
<code>element-available()</code>
functions have been updated to perform an evaluation at compile-time, so
that
the <code>If</code> class can know wether to compile in calls to extensions
or
not. This is possible because both functions take only literal expressions
as
parameters. See the <code>getResult()</code> methods of the
<code>FunctionAvailableCall</code> and <code>ElementAvailableCall</code>
classes for details.</p>
</s2>
</s1>
1.1 xml-xalan/java/xdocs/sources/xsltc/xsl_include_design.xml
Index: xsl_include_design.xml
===================================================================
<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
<!--
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Sun
* Microsystems., http://www.sun.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
-->
<s1 title="<xsl:include> / <xsl:import>">
<p><img src="xmllogo.gif"/></p>
<s2 title="Contents">
<ul>
<li><link anchor="functionality">Functionality</link></li>
<li><link anchor="implementation">Implementation</link></li>
</ul>
</s2>
<anchor name="functionality"/>
<s2 title="Functionality">
<p><code><xsl:include></code> allows you to include one stylesheet
into another. The includ<i>ed</i> stylesheet's templates will have the
same
default priorities and import precedence as the includ<i>ing</i>
stylesheet.
<code><xsl:import></code> offers the same, but the import precedence
of elements in an import<i>ed</i> stylesheet is always less than that of
the import<i>ing</i> stylesheet.</p>
</s2>
<anchor name="implementation"/>
<s2 title="Implementation">
<anchor name="include"/>
<s3 title="<xsl:include>">
<p>This is the simplest case, so we will look at that first. The algorithm
for including another stylesheet is roughly:</p>
<ul>
<li>get the including stylesheet from the XSLT parser</li>
<li>get the value of the "href" attribute from the
<code><xsl:include></code> element and check for circular
includes/imports</li>
<li>check if there is a defined <code>SourceLoader</code> set either
through the native or the TrAX API</li>
<li>get an <code>InputSource</code> for the document to include, either
from the <code>SourceLoader</code> or from the document's URI</li>
<li>parse the input document using the compiler's XSLT parser</li>
<li>set the import precedence of the included stylesheet to the same as
the import precedence of the including stylesheet</li>
<li>get the top-level stylesheet from the XSLT parser</li>
<li>move all variables, parameters, and top-level elements (include
templates) from the included stylesheet to the top-level stylesheet
(all elements will keep their import precedence even after being moved
to the top-level stylesheet)</li>
</ul>
</s3>
<anchor name="import"/>
<s3 title="<xsl:import>">
<p>This is very similar to <code><xsl:include></code>, but import
precedence has to be handled differently. Looking at the code you'll find
this fragment:</p><source>
// Handle precedence for the including stylesheet
final int currPrecedence = parser.getCurrentImportPrecedence();
final int nextPrecedence = parser.getNextImportPrecedence();
_imported.setImportPrecedence(currPrecedence);
context.setImportPrecedence(nextPrecedence);</source>
<p>The important thing here is that the imported stylesheet has import
precedence <i>less</i> than the importing stylesheet. So the imported
stylesheet gets the current import precedence, while the current
stylesheet
gets the next available (unused) import precedence. The
<code>Stylesheet</code> class has a method
<code>setImportPrecedence()</code> that ensures that the import precedence
is set not only for the stylesheet itself, but that it is also propagated
down to any included/imported stylesheets:</p><source>
public void setImportPrecedence(final int precedence) {
// Set import precedence for this stylesheet
_importPrecedence = precedence;
// Set import precedence for all included stylesheets
final Enumeration elements = elements();
while (elements.hasMoreElements()) {
SyntaxTreeNode child = (SyntaxTreeNode)elements.nextElement();
if (child instanceof Include) {
Stylesheet included = ((Include)child).getIncludedStylesheet();
if (included != null) included.setImportPrecedence(precedence);
}
}
// Set import precedence for the stylesheet that imported this one
if (_importedFrom != null) {
if (_importedFrom.getImportPrecedence() < precedence) {
final Parser parser = getParser();
final int nextPrecedence = parser.getNextImportPrecedence();
_importedFrom.setImportPrecedence(nextPrecedence);
}
}
// Set import precedence for the stylesheet that included this one
else if (_includedFrom != null) {
if (_includedFrom.getImportPrecedence() != precedence)
_includedFrom.setImportPrecedence(precedence);
}
}</source>
<p>This method has been carefully cluttered together, and it works, and it
should not be touched.</p>
</s3>
<anchor name="apply-imports"/>
<s3 title="<xsl:apply-imports>">
</s3>
</s2>
</s1>
1.1
xml-xalan/java/xdocs/sources/xsltc/xsl_variable_design.xml
Index: xsl_variable_design.xml
===================================================================
<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
<!--
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Sun
* Microsystems., http://www.sun.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
-->
<s1 title="<xsl:variable> / <xsl:param>">
<p><img src="xmllogo.gif"/></p>
<s2 title="Contents">
<ul>
<li><link anchor="functionality">Functionality</link></li>
<li><link anchor="implementation">Implementation</link></li>
</ul>
</s2>
<anchor name="functionality"/>
<s2 title="Functionality">
<p>Variables in XSLT are not really variables, as their values cannot be
changed. They resemble constants from conventional programming languages.
The
only way in which a variable can be changed is by declaring it inside a
for-each loop, in which case its value will be updated for every iteration.
Top-level variables (variables that are direct child nodes of the
<code><xsl:stylesheet></code> element) can never be changed.</p>
<source>
<xsl:for-each select="/foo/bar">
<xsl:variable name="some-bar" select="."/>
<xsl:value-of select="$some-bar"/>
</xsl:for-each></source>
<p>Parameters are assigned a value either from the process that invoked
the stylesheet (top-level parameter), or from a
<code><xsl:with-param></code> or from a default value (in which case
it
behaves as if it was a variable).</p>
<source>
<xsl:template match="/">
<xsl:call-template name="blob">
<xsl:with-param name="par" select="'some-value'"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="blob">
<xsl:param name="par" select="'default-value'"/>
<xsl:value-of select="$param"/>
</xsl:template></source>
</s2>
<anchor name="implementation"/>
<s2 title="Implementation">
<p>Variables and parameters share a common base class
<code>VariableBase</code> that contains a lot of common methods. This
class
handles both global and local variables/parameters.</p>
<s3 title="Top-level parameters and variables">
<p>All top-level (ie. global) parameters and variables are stored inside
fields in the translet class. Variables are stored as objects or basic
data types (such as boolean, char, int, etc.) while parameters have to be
"boxed" inside an object. This is because parameters are also stored as
objects inside the translet. The <code>addParameter()</code> method of the
<code>AbstractTranslet</code> class stores the parameter in a Hashtable
(the Hashtable maps the parameter name to the parameter value). The
"boxing" of the parameter's value is done by the class that handles the
parameters type. This class is a subclass of
<code>org.apache.xalan.xsltc.compiler.util.Type</code>.</p>
<p>Note that all top-level parameters and variables from all imported and
included stylesheets will be placed as direct children of the top-level
stylesheet in the AST. This done to make global variables truly global and
not just global in the stylesheet where it was declared.</p>
</s3>
<s3 title="Local parameters and variables">
<p>Local variables that are accessible from a given syntax tree node will
first be put on the JVM's stack and stored in a local variable slot. This
makes the variable or parameter accessible from all code within that
method. But, in some special cases, the code that is compiled to handle an
element/expression within the variable scope is not put inside the same
method as the actual variable. This is the case for some predicates.
All syntax-tree nodes implement the <code>isClosureBoundary()</code>
method
to indicate if its child an ancestor nodes will end up in a different
method
then itself. This method is used by the <code>Variable</code> and
<code>Param</code> classes to determine if the variable or parameter will
"escape" the variable frame.</p>
<source>
<xsl:for-each select="/foo/bar/baz">
<xsl:variable name="pos" select="3"/>
<xsl:apply-templates select="/foo/bar[$pos]"/>
</xsl:for-each></source>
<p>The predicate in this stylesheet fragment is compiled into a separate
auxiliary class that implements the <code>Filter</code> interface. It will
therefore not have access to the variable "pos" in the current stack
frame.
A common technique for cases like this is to use a <i>"closure"</i>. A
closure is a record that contains references to all variables that are in
scope for a certain part of the compiled scope. This is done in a very
simple manner in XSLTC. All variables or parameters that can "escape" the
stack are passed to the translet via its <code>addVariable()</code>
method.
They can then later be retrieved by the <code>getVariable()</code> method.
</p>
<p><i><b>Important note 1:</b></i> A predicate does not always result in a
auxiliary class. In some cases we optimize the code by using tailored
iterators and goodies like that instead. We may want to update the
predicate code to check if an auxiliary class will be generated before
returning true or false from the <code>isClosureBoundary()</code>
method.</p>
<p><i><b>Important note 2:</b></i> There could be other closure boundaries
that we have not yet discovered or considered. This could be, for
instance,
sort records and other auxiliary classes:</p>
<source>
<xsl:variable name="sort-order" select="'decending'"/>
<xsl:for-each select="/foo/bar/baz">
<xsl:sort select="@name" order="$sort-order"/>
<xsl:value-of select="."/>
</xsl:for-each></source>
<p>I would not be surprised if this fails. A fix could be to implement the
<code>isClosureBoundary()</code> in the <code>Sort</code> class and have
the
method return 'true' in all cases.</p>
</s3>
<s3 title="Parameter and variable references">
<p>A parameter or variable reference does the oposite of a parameter or
variable. The value is read from either a global field, a local variable
slot or from a call to <code>getVariable()</code> /
<code>getParameter()</code>. The chosen method depends is we're dealing
with
a parameter or a variable, a global or a local, an escaping variable or
not.
</p>
<p>The XPath parser identifies all variable references and instanciates
either a <code>VariableRef</code> or a <code>ParameterRef</code>. The
XPath
parser calls the parser's <code>lookupVariable</code> method in an initial
attempt to find the variable/parameter instance. If that fails, it goes on
to call the symbol table's <code>lookupName()</code> method. If that also
fails this means that either:</p>
<ul>
<li>a variable or parameter with the given name does not exist</li>
<li>the variable will be declared at a later stage
(but within the same scope)</li>
</ul>
<p>The XPath parser creates an instance of the <code>UnresolvedRef</code>
class. This class attempts to locate the variable after the whole AST has
been built, when the <code>typeCheck()</code> method is called. If this
fails an error is reported and the compilation stops. Otherwise the class
creates a <code>VariableRef</code> or a <code>ParameterRef</code> instance
and lets that handle the reference.</p>
</s3>
<s3 title="Forward references">
<p>XSLTC allows for forward references to global variables and parameters.
You can even reference variables in not-yet included/imported stylesheets.
In most cases, this is handled by changing the order of top-level
elements.
(Variables are placed first so that they are handled before any includes
or imports). But when a variable contains references to other variables,
then this requires some extra code in the <code>Stylesheet</code> and
<code>VariableBase</code> classes. The <code>VariableBase</code> has a
method that returns a vector containing all variables that are referenced
in the variable definition.</p>
<source>
<xsl:variable name="C" select="$A < $B"/>
<xsl:variable name="A" select="1"/>
<xsl:variable name="B" select="2"/></source>
<p>In this case, the <code>getDependencies()</code> method for variable
C will return the variables A and B. The stylesheet has a method called
<code>resolveReferences</code> that will order the variables accordingly
so that the variable values are computed in the desired order. This method
will issue an error message and terminate the compilation if there are
circular variable/parameter dependencies.</p>
</s3>
</s2>
</s1>
1.1 xml-xalan/java/xdocs/sources/xsltc/xsltc_performance.xml
Index: xsltc_performance.xml
===================================================================
<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
<!--
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Sun
* Microsystems., http://www.sun.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
-->
<s1 title="XSLTC Performance">
<p><img src="xmllogo.gif"/></p>
<s2 title="Introduction">
<p><i>XSLT is not a programming language!</i> Just so you remember.
XSLT is a declarative language and can be used by you to describe
<i><b>what</b></i> you want put in your output document and
<i><b>what</b></i> you want this output to look like. It does not describe
<i><b>how</b></i> these taks should be carried. That is the job of the
XSLT
processor. This document is <u>not</u> a "<i>programmer's guide to
XSLT</i>"
and should not be considered as such. All XSLT processors have their
properties and ways of handling XSL elements and XPath properties. This
document will give you some insight into the XSLTC internals, so that you
can channel your stylesheets through XSLTC's shortest and most efficient
code paths.</p>
<p>XSLTC's performance has always been one of its key selling points.
(I should probably find a better term here, since we're giving XSLTC away
for free.) But, there are some specific patterns and expressions that are
not handled much better than with other interpretive XSLT processors, and
this document is an attempt to pinpoint these and to outline alternatives.
</p>
</s2>
<s2 title="Contents">
<ul>
<li><link anchor="pred">Avoid using predicates in '*'
patterns</link></li>
<li><link anchor="idkey">Avoid using id/key-patterns</link></li>
<li><link anchor="union">Avoid union expressions where
possible</link></li>
<li><link anchor="sort">Sort stored node-sets once</link></li>
<li><link anchor="cache">Cache input documents</link></li>
<li><link anchor="trax">TrAX vs. native API</link></li>
</ul>
</s2>
<anchor name="pred"/>
<s2 title="Avoid using predicates in wildcard patterns">
<p>XSLTC gains its speed from the simple dispatch loop in the translet's
<code>applyTemplates()</code> method. This method uses a simple
<code>switch()</code> statement to choose the desired template based on
the current node's node type (an integer). By adding a pattern with a
wildcard (no type) and a predicate, XSLTC is forced to evaluate the
predicate for every single node.</p><source>
<xsl:template match="*[2]"></source>
<p>The above pattern should be avoided by selecting the desired node when
using <code><xsl:apply-templates></code>. Use named templates or
modes to make sure you trigger the correct template:</p><source>
<xsl:template match="/">
<xsl:apply-templates select="bar"/>
</xsl:template>
<xsl:template match="*[2]"/>
<xsl:template match="*"/></source>
<p>can be replaced by:</p><source>
<xsl:template match="/">
<xsl:apply-templates select="bar"/>
<xsl:apply-templates select="bar[2]" mode="second"/>
</xsl:template>
<xsl:template match="*" mode="second"/>
<xsl:template match="*"/></source>
<p>This change will only improve performance if the stylesheet is fairly
large and has a good few templates (10 or more). Also note that the order
of the output is changed by this approach, so if the order is significant
you'll have to stick to the original stylesheet.</p>
<p><i><b>Important note:</b></i> The type of pattern referred to as a
type-less pattern, as it does not match any specific node type. Such
patterns do in general degrade the performance of XSLTC. Type-less
patterns
must be evaluated for every single node in the input document - causing a
general performance degradation.</p>
</s2>
<anchor name="idkey"/>
<s2 title="Avoid using id/key-patterns">
<p>Id and key patterns can be used to trigger a template if the current
node has a specific id or has a specific value in a key's
index:</p><source>
<xsl:template match="id('some-value')"/>
<xsl:template match="key('key-name', 'some-value')"/></source>
<p>Looking up a value/node-pair in an index does not require much
processing
time at all. But, this is also a type-less pattern and can match any type
of node. This degrades XSLTC's performenace, just like wildcard patterns
with predicates (see above paragraph).</p>
</s2>
<anchor name="union"/>
<s2 title="Avoid union expressions where possible">
<p>Union expressions provide an all-in-one-go easy way of applying
templates
to sets of nodes:</p><source>
<xsl:apply-templates select="foo|bar|baz"/></source>
<p>The union iterator that is used to implement union expressions is
unfortunately not very efficient. If node order is not of importance, then
one can benefit from breaking the union up in several
elements:</p><source>
<xsl:apply-templates select="foo"/>
<xsl:apply-templates select="bar"/>
<xsl:apply-templates select="baz"/></source>
<p>But, remeber that this will give you all <code><foo></code>
elements first, then all <code><bar></code> elements, and so on.
This is not always desireable. You may want to handle these elements in
the order in which they appear in the input document.</p>
<p><b>Important note:</b> This does <u>not</u> apply to union patterns.
Using unions in patterns actually makes smaller and more efficient code,
as only one copy of the templete body has to be compiled. Use:</p><source>
<xsl:template match="foo|bar|baz"/></source>
<p>instead of:</p><source>
<xsl:template match="foo"/>
<xsl:template match="bar"/>
<xsl:template match="baz"/></source>
</s2>
<anchor name="sort"/>
<s2 title="Sort stored node-sets once">
<p>This item is very obvious, but nevertheless easy to forget in some
complicated cases. If you put a result-tree fragment inside a variable,
and
you want the nodes in a specific, sorted order, then sort the nodes as you
create the variable and not when you use it. Instead of:</p><source>
<xsl:variable name="bars">
<xsl:copy-of select="//foo/bar"/>
</xsl:variable>
<xsl:template match="/">
<xsl:text>List of bar's in sorted order:&#xa;</xsl:text>
<xsl:for-each select="$bars-sorted">
<xsl:value-of select="@name"/>
<xsl:text>&#xa;</xsl:text>
</xsl:for-each>
</xsl:template></source>
<p>A better way, and with most XSLT processors the only legal way, is to
sort the result tree when creating it:</p><source>
<xsl:variable name="bars">
<xsl:for-each select="//foo/bar">
<xsl:sort select="@name"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<xsl:text>List of bar's in sorted order:&#xa;</xsl:text>
<xsl:for-each select="$bars">
<xsl:value-of select="@name"/>
<xsl:text>&#xa;</xsl:text>
</xsl:for-each>
</xsl:template></source>
<p>It is very common to sort node-sets returned by the id() and key()
functions. Instead of doing this sorting over and over again, one should
use a variable and store the node set in the desired sort order, and read
the node set from the variable whenever used.</p>
</s2>
<anchor name="cache"/>
<s2 title="Cache the input document">
<p>All XSLT processors use an internal DOM-like structure, and XSLTC is no
exception. The internal DOM is tailored for the XSLTC design and can be
navigated efficiently by the translet. Building the internal DOM is a
rather slow process, and does very many cases take more time than the
actual transformation. This is a general rule, and does not only apply to
XSLTC. It is advisable, and common in most large-scale XSLT-based
applications, to create a cache for the input documents. Not only does
this
prevent CPU- and memory-intensive DOM creation, but it also prevents
several
translets from having their own private copies of common input documents.
Both XSLTC's internal API and TrAX implementation provide ways of
implementing a decent input document cache:</p>
<ul>
<li>See <link anchor="trax-cache">below</link> for a description of how
to do this using the TrAX interface.</li>
<li>The <jump href="xsltc_native_api.html#document-locator">native API
documentation</jump> contains a section on using the internal
<code>org.apache.xalan.xsltc.compiler.SourceLoader</code>
interface.</li>
</ul>
</s2>
<anchor name="trax"/>
<s2 title="TrAX vs. native API">
<s4 title="TrAX performance benefits">
<p>If XSLTC's two-step approach to XSLT processing suits your application
then there is no reason why you should not use the TrAX API. The API fits
very nicely in with XSLTC internals and processing model. In fact, you may
even benefit from using TrAX in cases where your stylesheet is compiled
into a large ammount of auxiliary classes. The most obvious benefit is
that
the translet class and auxiliary classes are all bundled inside the
<code>Templates</code> object. Performance can also be improved due to the
fact that XSLTC chaches all auxiliary classes inside
<code>Templates</code>
code, preventing the class loader from being invoked more than necessary.
This is just theory and no tests have been done, but you should see a
performance improvement when using XSLTC and TrAX in such cases.</p>
</s4>
<s4 title="Treat Templates objects as compiled translets">
<p>When using TrAX, the <code>Templates</code> object should be considered
the result of a compilation. With XSLTC this is the actual case - the
<code>Templates</code> object contains the translet Java class(es). With
other XSLT processors the <code>Templates</code> directly or indirectly
contains data-structures represent all or parts of the input stylesheet.
The bottom line is: Create your <code>Templates</code> object once, cache
and re-use it as often as possible.</p>
</s4>
<anchor name="trax-cache"/>
<s4 title="Input document caching">
<p>An extension to the TrAX API allows input documents to be cached. The
extensions is a sub-class to the TrAX <code>Source</code> class, which can
be used to wrap XSLTC's internal DOM structures. This is described in
detail in the <link idref="xsltc_trax_api">XSLTC TrAX API
reference</link>.
</p>
<p>If you do chose to implement a DOM cache, you should have your cache
implement the <code>javax.xml.transform.URIResolver</code> interface so
that documents loaded by the <code>document()</code> function are also
read
from your cache.</p>
</s4>
</s2>
</s1>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]