blob: 4e1be0d5a299f6e01ea1743bf487f52874b2f7ce [file] [log] [blame]
<?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 apache@apache.org.
*
* 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="&lt;xsl:include&gt; / &lt;xsl:import&gt;">
<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>&lt;xsl:include&gt;</code> allows you to include one stylesheet
into another. The includ<em>ed</em> stylesheet's templates will have the same
default priorities and import precedence as the includ<em>ing</em> stylesheet.
<code>&lt;xsl:import&gt;</code> offers the same, but the import precedence
of elements in an import<em>ed</em> stylesheet is always less than that of
the import<em>ing</em> stylesheet.</p>
</s2>
<anchor name="implementation"/>
<s2 title="Implementation">
<anchor name="include"/>
<s3 title="&lt;xsl:include&gt;">
<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>&lt;xsl:include&gt;</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="&lt;xsl:import&gt;">
<p>This is very similar to <code>&lt;xsl:include&gt;</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 <em>less</em> 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() &lt; 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="&lt;xsl:apply-imports&gt;">
</s3>
</s2>
</s1>