in xalan/src/main/java/org/apache/xalan/transformer/TransformerImpl.java [2130:2296]
public boolean applyTemplateToNode(ElemTemplateElement xslInstruction, // xsl:apply-templates or xsl:for-each
ElemTemplate template, int child)
throws TransformerException
{
DTM dtm = m_xcontext.getDTM(child);
short nodeType = dtm.getNodeType(child);
boolean isDefaultTextRule = false;
boolean isApplyImports = false;
isApplyImports = ((xslInstruction == null)
? false
: xslInstruction.getXSLToken()
== Constants.ELEMNAME_APPLY_IMPORTS);
if (null == template || isApplyImports)
{
int maxImportLevel, endImportLevel=0;
if (isApplyImports)
{
maxImportLevel =
template.getStylesheetComposed().getImportCountComposed() - 1;
endImportLevel =
template.getStylesheetComposed().getEndImportCountComposed();
}
else
{
maxImportLevel = -1;
}
// If we're trying an xsl:apply-imports at the top level (ie there are no
// imported stylesheets), we need to indicate that there is no matching template.
// The above logic will calculate a maxImportLevel of -1 which indicates
// that we should find any template. This is because a value of -1 for
// maxImportLevel has a special meaning. But we don't want that.
// We want to match -no- templates. See bugzilla bug 1170.
if (isApplyImports && (maxImportLevel == -1))
{
template = null;
}
else
{
// Find the XSL template that is the best match for the
// element.
XPathContext xctxt = m_xcontext;
try
{
xctxt.pushNamespaceContext(xslInstruction);
QName mode = this.getMode();
if (isApplyImports)
template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode,
maxImportLevel, endImportLevel, m_quietConflictWarnings, dtm);
else
template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode,
m_quietConflictWarnings, dtm);
}
finally
{
xctxt.popNamespaceContext();
}
}
// If that didn't locate a node, fall back to a default template rule.
// See http://www.w3.org/TR/xslt#built-in-rule.
if (null == template)
{
switch (nodeType)
{
case DTM.DOCUMENT_FRAGMENT_NODE :
case DTM.ELEMENT_NODE :
template = m_stylesheetRoot.getDefaultRule();
break;
case DTM.CDATA_SECTION_NODE :
case DTM.TEXT_NODE :
case DTM.ATTRIBUTE_NODE :
template = m_stylesheetRoot.getDefaultTextRule();
isDefaultTextRule = true;
break;
case DTM.DOCUMENT_NODE :
template = m_stylesheetRoot.getDefaultRootRule();
break;
default :
// No default rules for processing instructions and the like.
return false;
}
}
}
// If we are processing the default text rule, then just clone
// the value directly to the result tree.
try
{
pushElemTemplateElement(template);
m_xcontext.pushCurrentNode(child);
pushPairCurrentMatched(template, child);
// Fix copy copy29 test.
if (!isApplyImports) {
DTMIterator cnl = new org.apache.xpath.NodeSetDTM(child, m_xcontext.getDTMManager());
m_xcontext.pushContextNodeList(cnl);
}
if (isDefaultTextRule)
{
switch (nodeType)
{
case DTM.CDATA_SECTION_NODE :
case DTM.TEXT_NODE :
ClonerToResultTree.cloneToResultTree(child, nodeType,
dtm, getResultTreeHandler(), false);
break;
case DTM.ATTRIBUTE_NODE :
dtm.dispatchCharactersEvents(child, getResultTreeHandler(), false);
break;
}
}
else
{
// Fire a trace event for the template.
if (m_debug)
getTraceManager().fireTraceEvent(template);
// And execute the child templates.
// 9/11/00: If template has been compiled, hand off to it
// since much (most? all?) of the processing has been inlined.
// (It would be nice if there was a single entry point that
// worked for both... but the interpretive system works by
// having the Transformer execute the children, while the
// compiled obviously has to run its own code. It's
// also unclear that "execute" is really the right name for
// that entry point.)
m_xcontext.setSAXLocator(template);
// m_xcontext.getVarStack().link();
m_xcontext.getVarStack().link(template.m_frameSize);
executeChildTemplates(template, true);
if (m_debug)
getTraceManager().fireTraceEndEvent(template);
}
}
catch (org.xml.sax.SAXException se)
{
throw new TransformerException(se);
}
finally
{
if (!isDefaultTextRule)
m_xcontext.getVarStack().unlink();
m_xcontext.popCurrentNode();
if (!isApplyImports) {
m_xcontext.popContextNodeList();
}
popCurrentMatched();
popElemTemplateElement();
}
return true;
}