<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
<!--
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
-->
<!-- $Id$ -->
  <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>
