You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sb...@apache.org on 2001/06/03 05:20:57 UTC
cvs commit: xml-xalan/java/src/org/apache/xalan/templates ElemApplyTemplates.java ElemForEach.java
sboag 01/06/02 20:20:57
Modified: java/src/org/apache/xalan/templates Tag: DTM_EXP
ElemApplyTemplates.java ElemForEach.java
Log:
High tuning of the for-each loop, with steps towards a non-recursive
walk of the stylesheet tree, or at least within the same xsl:template.
Revision Changes Path
No revision
No revision
1.13.2.3 +167 -41 xml-xalan/java/src/org/apache/xalan/templates/ElemApplyTemplates.java
Index: ElemApplyTemplates.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemApplyTemplates.java,v
retrieving revision 1.13.2.2
retrieving revision 1.13.2.3
diff -u -r1.13.2.2 -r1.13.2.3
--- ElemApplyTemplates.java 2001/05/06 02:09:27 1.13.2.2
+++ ElemApplyTemplates.java 2001/06/03 03:20:56 1.13.2.3
@@ -57,7 +57,6 @@
package org.apache.xalan.templates;
//import org.w3c.dom.*;
-
import org.xml.sax.*;
import org.apache.xpath.*;
@@ -72,8 +71,13 @@
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xalan.transformer.ResultTreeHandler;
import org.apache.xalan.transformer.ClonerToResultTree;
+import org.apache.xml.dtm.DTMAxisTraverser;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.Axis;
import javax.xml.transform.TransformerException;
+import javax.xml.transform.SourceLocator;
/**
* <meta name="usage" content="advanced"/>
@@ -131,7 +135,7 @@
* regard to processing modes.
* @see <a href="http://www.w3.org/TR/xslt#built-in-rule">built-in-rule in XSLT Specification</a>
*
- * @param b boolean value to set.
+ * @param b boolean value to set.
*/
public void setIsDefaultTemplate(boolean b)
{
@@ -169,54 +173,165 @@
*
* @throws TransformerException
*/
- public void execute(
- TransformerImpl transformer)
- throws TransformerException
+ public void execute(TransformerImpl transformer) throws TransformerException
{
transformer.pushCurrentTemplateRuleIsNull(false);
boolean pushMode = false;
-
+
try
{
if (TransformerImpl.S_DEBUG)
transformer.getTraceManager().fireTraceEvent(this);
-
- // %REVIEW% Do we need this check??
-// if (null != sourceNode)
-// {
-
- // boolean needToTurnOffInfiniteLoopCheck = false;
- QName mode = transformer.getMode();
- if (!m_isDefaultTemplate)
+
+ // %REVIEW% Do we need this check??
+ // if (null != sourceNode)
+ // {
+ // boolean needToTurnOffInfiniteLoopCheck = false;
+ QName mode = transformer.getMode();
+
+ if (!m_isDefaultTemplate)
+ {
+ if (((null == mode) && (null != m_mode))
+ || ((null != mode) &&!mode.equals(m_mode)))
{
- if(((null == mode) && (null != m_mode) ) ||
- ((null != mode) && !mode.equals(m_mode)))
- {
- pushMode = true;
- transformer.pushMode(m_mode);
- }
+ pushMode = true;
+
+ transformer.pushMode(m_mode);
}
+ transformSelectedNodes(transformer, null);
+ }
+ else
+ {
transformSelectedNodes(transformer, null);
-// }
-// else // if(null == sourceNode)
-// {
-// transformer.getMsgMgr().error(this,
-// XSLTErrorResources.ER_NULL_SOURCENODE_HANDLEAPPLYTEMPLATES); //"sourceNode is null in handleApplyTemplatesInstruction!");
-// }
+ // The code below would work, except for the context node list. -sb
+// try
+// {
+// boolean rdebug = TransformerImpl.S_DEBUG;
+// XPathContext xctxt = transformer.getXPathContext();
+// int sourceNode = xctxt.getCurrentNode();
+//
+// if (rdebug)
+// transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
+// "test", getSelectOrDefault(),
+// new org.apache.xpath.objects.XNodeSet(
+// getSelectOrDefault().getExpression().asIterator(xctxt,
+// sourceNode))); // ugly as sin.
+//
+// xctxt.pushContextNodeList((DTMIterator)getSelectOrDefault().getExpression()); // ?? Will it do?
+// transformer.pushElemTemplateElement(null);
+//
+// ResultTreeHandler rth = transformer.getResultTreeHandler();
+// StylesheetRoot sroot = getStylesheetRoot();
+// TemplateList tl = sroot.getTemplateListComposed();
+// SourceLocator savedLocator = xctxt.getSAXLocator();
+// boolean quiet = transformer.getQuietConflictWarnings();
+//
+// try
+// {
+// int child;
+// DTM dtm = xctxt.getDTM(sourceNode);
+// DTMAxisTraverser traverser = dtm.getAxisTraverser(Axis.CHILD);
+//
+// for (child = traverser.first(sourceNode); DTM.NULL != child;
+// child = traverser.next(sourceNode, child))
+// {
+//
+// mode = transformer.getMode();
+//
+// ElemTemplate template = tl.getTemplate(xctxt, child, mode,
+// -1, quiet, dtm);
+//
+// // 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 (dtm.getNodeType(child))
+// {
+// case DTM.DOCUMENT_FRAGMENT_NODE :
+// case DTM.ELEMENT_NODE :
+// template = sroot.getDefaultRule();
+// break;
+// case DTM.ATTRIBUTE_NODE :
+// case DTM.CDATA_SECTION_NODE :
+// case DTM.TEXT_NODE :
+// dtm.dispatchCharactersEvents(child, rth, false);
+//
+// continue;
+// case DTM.DOCUMENT_NODE :
+// template = sroot.getDefaultRootRule();
+// break;
+// default :
+//
+// // No default rules for processing instructions and the like.
+// continue;
+// }
+// }
+//
+// ElemTemplateElement t = template.m_firstChild;
+//
+// // If we are processing the default text rule, then just clone
+// // the value directly to the result tree.
+// try
+// {
+// xctxt.pushCurrentNode(child);
+//
+// transformer.pushPairCurrentMatched(template, child);
+//
+// // Fire a trace event for the template.
+// if (rdebug)
+// transformer.getTraceManager().fireTraceEvent(template);
+//
+// // And execute the child templates.
+// // Loop through the children of the template, calling execute on
+// // each of them.
+// for (; t != null; t = t.m_nextSibling)
+// {
+// xctxt.setSAXLocator(t);
+// transformer.setCurrentElement(t);
+// t.execute(transformer);
+// }
+//
+// // reMarkParams(xctxt);
+// }
+// finally
+// {
+// xctxt.popCurrentNode();
+// transformer.popCurrentMatched();
+// }
+// }
+// }
+// finally
+// {
+// xctxt.setSAXLocator(savedLocator);
+// xctxt.popContextNodeList();
+// transformer.popElemTemplateElement();
+// // popParams(xctxt, savedSearchStart);
+//
+// // if(null != sourceNodes)
+// // sourceNodes.detach();
+// }
+// }
+// catch (SAXException se)
+// {
+// transformer.getErrorListener().fatalError(
+// new TransformerException(se));
+// }
+ }
}
finally
{
- if(pushMode)
+ if (pushMode)
transformer.popMode();
+
transformer.popCurrentTemplateRuleIsNull();
}
}
/**
- * Return whether or not we need to push default arguments on the stack
+ * Return whether or not we need to push default arguments on the stack
*
*
* @return whether or not to push default arguments on the stack
@@ -225,6 +340,7 @@
{
return true;
}
+
/**
* Push default arguments on the stack
@@ -238,41 +354,47 @@
* @return The original value of where to start the current search for a variable.
* This value will be used by popParams to restore the value of
* VariableStack.m_searchStart.
- *
+ *
* @throws TransformerException
*/
- int pushParams(
- TransformerImpl transformer, XPathContext xctxt)
- throws TransformerException
+ int pushParams(TransformerImpl transformer, XPathContext xctxt)
+ throws TransformerException
{
+ if(m_isDefaultTemplate)
+ return 0;
VariableStack vars = xctxt.getVarStack();
- int savedSearchStart = vars.getSearchStart();
-
+ int savedSearchStart = vars.getSearchStart();
+
if (null != m_paramElems)
- {
+ {
transformer.pushParams(xctxt, this);
- }
+ }
else
vars.pushContextMarker();
-
+
vars.setSearchStart(-1);
-
+
return savedSearchStart;
}
-
+
/**
* Re-mark the params as params.
+ *
+ * NEEDSDOC @param xctxt
*/
void reMarkParams(XPathContext xctxt)
{
+ if(m_isDefaultTemplate)
+ return;
+
VariableStack vars = xctxt.getVarStack();
+
vars.remarkParams();
}
-
/**
- * Pop the stack of default arguments after we're done with them
+ * Pop the stack of default arguments after we're done with them
*
*
* @param xctxt The XPath runtime state for this transformation.
@@ -281,7 +403,11 @@
*/
void popParams(XPathContext xctxt, int savedSearchStart)
{
+ if(m_isDefaultTemplate)
+ return;
+
VariableStack vars = xctxt.getVarStack();
+
vars.popCurrentContext();
vars.setSearchStart(savedSearchStart);
}
1.20.2.7 +182 -98 xml-xalan/java/src/org/apache/xalan/templates/ElemForEach.java
Index: ElemForEach.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/templates/ElemForEach.java,v
retrieving revision 1.20.2.6
retrieving revision 1.20.2.7
diff -u -r1.20.2.6 -r1.20.2.7
--- ElemForEach.java 2001/05/30 20:30:46 1.20.2.6
+++ ElemForEach.java 2001/06/03 03:20:56 1.20.2.7
@@ -58,9 +58,12 @@
//import org.w3c.dom.*;
//import org.w3c.dom.traversal.NodeIterator;
-
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+
+// Experemental
+import org.apache.xml.dtm.ref.ExpandedNameTable;
import org.xml.sax.*;
@@ -77,6 +80,7 @@
import org.apache.xalan.transformer.NodeSorter;
import org.apache.xalan.transformer.ResultTreeHandler;
import org.apache.xalan.transformer.StackGuard;
+import org.apache.xalan.transformer.ClonerToResultTree;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
@@ -111,7 +115,7 @@
* The "select" expression.
* @serial
*/
- private XPath m_selectExpression = null;
+ protected Expression m_selectExpression = null;
/**
* Set the "select" attribute.
@@ -120,7 +124,7 @@
*/
public void setSelect(XPath xpath)
{
- m_selectExpression = xpath;
+ m_selectExpression = xpath.getExpression();
}
/**
@@ -128,25 +132,33 @@
*
* @return The XPath expression for the "select" attribute.
*/
- public XPath getSelect()
+ public Expression getSelect()
{
return m_selectExpression;
}
/**
- * Get the "select" attribute or default selection pattern.
+ * This function is called after everything else has been
+ * recomposed, and allows the template to set remaining
+ * values that may be based on some other property that
+ * depends on recomposition.
*
- * @return the "select" attribute or if null, the
- * default selection pattern ("node()")
+ * @throws TransformerException
*/
- public XPath getSelectOrDefault()
+ public void compose() throws TransformerException
{
- return (null == m_selectExpression)
- ? getStylesheetRoot().m_selectDefault : m_selectExpression;
+
+ if (null == m_selectExpression)
+ {
+ m_selectExpression =
+ getStylesheetRoot().m_selectDefault.getExpression();
+ }
}
- /** Vector containing the xsl:sort elements associated with this element.
- * @serial */
+ /**
+ * Vector containing the xsl:sort elements associated with this element.
+ * @serial
+ */
protected Vector m_sortElems = null;
/**
@@ -206,15 +218,13 @@
}
/**
- * Execute the xsl:for-each transformation
+ * Execute the xsl:for-each transformation
*
* @param transformer non-null reference to the the current transform-time state.
*
* @throws TransformerException
*/
- public void execute(
- TransformerImpl transformer)
- throws TransformerException
+ public void execute(TransformerImpl transformer) throws TransformerException
{
transformer.pushCurrentTemplateRuleIsNull(true);
@@ -247,7 +257,7 @@
* Sort given nodes
*
*
- * @param xctxt The XPath runtime state for the sort.
+ * @param xctxt The XPath runtime state for the sort.
* @param keys Vector of sort keyx
* @param sourceNodes Iterator of nodes to sort
*
@@ -261,10 +271,9 @@
{
NodeSorter sorter = new NodeSorter(xctxt);
-
+
sourceNodes.setShouldCacheNodes(true);
sourceNodes.runTo(-1);
-
xctxt.pushContextNodeList(sourceNodes);
try
@@ -281,7 +290,7 @@
}
/**
- * Return whether or not default parameters need to be pushed into stack
+ * Return whether or not default parameters need to be pushed into stack
*
*
* @return False, no need to push parameters here.
@@ -292,7 +301,7 @@
}
/**
- * Push default parameters into the stack
+ * Push default parameters into the stack
*
*
* @param transformer non-null reference to the the current transform-time state.
@@ -300,38 +309,38 @@
* @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
* @param mode reference, which may be null, to the <a href="http://www.w3.org/TR/xslt#modes">current mode</a>.
*
- * @return -1, this return will not be used by ElemForEach.
+ * @return -1, this return will not be used by ElemForEach.
* It is just there because ElemApplyTemplates which derives
* from this needs to that value to be saved.
- *
+ *
* @throws TransformerException
*/
- int pushParams(
- TransformerImpl transformer, XPathContext xctxt)
- throws TransformerException
+ int pushParams(TransformerImpl transformer, XPathContext xctxt)
+ throws TransformerException
{
VariableStack vars = xctxt.getVarStack();
vars.pushElemFrame();
+
return -1;
}
-
+
/**
* Re-mark the params as params.
+ *
+ * NEEDSDOC @param xctxt
*/
- void reMarkParams(XPathContext xctxt)
- {
- }
+ void reMarkParams(XPathContext xctxt){}
/**
- * Pop Default parameters from the stack
+ * Pop Default parameters from the stack
*
*
* @param xctxt The XPath runtime state.
- * @param savedSearchStart This param will not be used by ElemForEach.
+ * @param savedSearchStart This param will not be used by ElemForEach.
* It is just there because ElemApplyTemplates which derives
- * from this needs to restore that value.
+ * from this needs to restore that value.
*/
void popParams(XPathContext xctxt, int savedSearchStart)
{
@@ -347,74 +356,88 @@
*
* @param transformer non-null reference to the the current transform-time state.
* @param template The owning template context.
- *
+ *
* @throws TransformerException Thrown in a variety of circumstances.
*/
public void transformSelectedNodes(
TransformerImpl transformer, ElemTemplateElement template)
throws TransformerException
{
+
+ final XPathContext xctxt = transformer.getXPathContext();
+ final int sourceNode = xctxt.getCurrentNode();
+ DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, sourceNode);
+
try
{
- boolean rdebug = TransformerImpl.S_DEBUG;
- XPathContext xctxt = transformer.getXPathContext();
- XPath selectPattern = getSelectOrDefault();
- int sourceNode = xctxt.getCurrentNode();
- XObject selectResult = selectPattern.execute(xctxt, sourceNode, this);
-
- if (rdebug)
- transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
- "test", selectPattern, selectResult);
-
- Vector keys = transformer.processSortKeys(this, sourceNode);
- DTMIterator sourceNodes = selectResult.nodeset();
+
+ // if (TransformerImpl.S_DEBUG)
+ // transformer.getTraceManager().fireSelectedEvent(sourceNode, this,
+ // "test", m_selectExpression,
+ // new org.apache.xpath.objects.XNodeSet(sourceNodes));
+ final Vector keys = (m_sortElems == null)
+ ? null
+ : transformer.processSortKeys(this, sourceNode);
// Sort if we need to.
if (null != keys)
sourceNodes = sortNodes(xctxt, keys, sourceNodes);
- // The returned value is only relevant for ElemApplyTemplates.
- // This value needs to be passed to popParams which will
- // restore it in the variable stack.
- int savedSearchStart = pushParams(transformer, xctxt);
-
- // Push the ContextNodeList on a stack, so that select="position()"
- // and the like will work.
- // System.out.println("pushing context node list...");
- SourceLocator savedLocator = xctxt.getSAXLocator();
-
- xctxt.pushContextNodeList(sourceNodes);
- transformer.pushElemTemplateElement(null);
-
- ResultTreeHandler rth = transformer.getResultTreeHandler();
- StylesheetRoot sroot = getStylesheetRoot();
- TemplateList tl = sroot.getTemplateListComposed();
+ final ResultTreeHandler rth = transformer.getResultTreeHandler();
+ ContentHandler chandler = rth.getContentHandler();
+ final StylesheetRoot sroot = getStylesheetRoot();
+ final TemplateList tl = sroot.getTemplateListComposed();
+ final boolean needToFindTemplate = (null == template);
+ final boolean quiet = transformer.getQuietConflictWarnings();
+
+ xctxt.pushCurrentNode(DTM.NULL);
+ int[] currentNodes = xctxt.getCurrentNodeStack();
+ int currentNodePos = xctxt.getCurrentNodeFirstFree() - 1;
+
+ xctxt.pushCurrentExpressionNode(DTM.NULL);
+ int[] currentExpressionNodes = xctxt.getCurrentExpressionNodeStack();
+ int currentExpressionNodePos = xctxt.getCurrentExpressionNodesFirstFree() - 1;
// StylesheetComposed stylesheet = getStylesheetComposed();
- StackGuard guard = transformer.getStackGuard();
- boolean check = (guard.m_recursionLimit > -1);
- boolean quiet = transformer.getQuietConflictWarnings();
- boolean needToFindTemplate = (null == template);
-
+ boolean didSetVars = false;
+ SourceLocator savedLocator = null;
+ StackGuard guard = null;
+ boolean check = false;
+ int savedSearchStart = 0;
+
try
{
+ // Should be able to get this from the iterator but there must be a bug.
+ DTM dtm = xctxt.getDTM(sourceNode);
+ int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
+
int child;
-
while (DTM.NULL != (child = sourceNodes.nextNode()))
{
- // System.out.println("child: "+child);
- DTM dtm = xctxt.getDTM(child);
+ currentNodes[currentNodePos] = child;
+ currentExpressionNodes[currentExpressionNodePos] = child;
+
+ if((child & DTMManager.IDENT_DTM_DEFAULT) != docID)
+ {
+ dtm = xctxt.getDTM(child);
+ docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
+ }
+
+ final int exNodeType = dtm.getExpandedTypeID(child);
+ final int nodeType = (exNodeType >> ExpandedNameTable.ROTAMOUNT_TYPE);
+
if (needToFindTemplate)
{
- QName mode = transformer.getMode();
-
- template = tl.getTemplate(xctxt, child, mode, -1, quiet, dtm);
+ final QName mode = transformer.getMode();
+
+ template = tl.getTemplateFast(xctxt, child, exNodeType, mode,
+ -1, quiet, dtm);
// 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 (dtm.getNodeType(child))
+ switch (nodeType)
{
case DTM.DOCUMENT_FRAGMENT_NODE :
case DTM.ELEMENT_NODE :
@@ -423,7 +446,8 @@
case DTM.ATTRIBUTE_NODE :
case DTM.CDATA_SECTION_NODE :
case DTM.TEXT_NODE :
- dtm.dispatchCharactersEvents(child, rth, false);
+ rth.flushPending(true);
+ dtm.dispatchCharactersEvents(child, chandler, false);
continue;
case DTM.DOCUMENT_NODE :
template = sroot.getDefaultRootRule();
@@ -436,46 +460,96 @@
}
}
+ if (!didSetVars)
+ {
+ didSetVars = true;
+ guard = transformer.getStackGuard();
+ check = (guard.m_recursionLimit > -1);
+
+ savedLocator = xctxt.getSAXLocator();
+
+ xctxt.pushContextNodeList(sourceNodes);
+ transformer.pushElemTemplateElement(null);
+
+ savedSearchStart = pushParams(transformer, xctxt);
+ }
+
ElemTemplateElement t = template.m_firstChild;
-
+
// If we are processing the default text rule, then just clone
// the value directly to the result tree.
try
- {
- xctxt.pushCurrentNode(child);
- if(needToFindTemplate)
+ {
+ if (needToFindTemplate)
transformer.pushPairCurrentMatched(template, child);
if (check)
guard.push(this, child);
// Fire a trace event for the template.
- if (rdebug)
+ if (TransformerImpl.S_DEBUG)
transformer.getTraceManager().fireTraceEvent(template);
// And execute the child templates.
- // %XTBD% ???
-// if (template.isCompiledTemplate())
-// template.execute(transformer, child, mode);
-// else
+ // Loop through the children of the template, calling execute on
+ // each of them.
+ for (; t != null; t = t.m_nextSibling)
{
+ xctxt.setSAXLocator(t);
+ transformer.setCurrentElement(t);
- // Loop through the children of the template, calling execute on
- // each of them.
- for (; t != null;
- t = t.m_nextSibling)
+ switch (t.getXSLToken())
{
- xctxt.setSAXLocator(t);
- transformer.setCurrentElement(t);
+ case Constants.ELEMNAME_COPY :
+
+ if ((DTM.DOCUMENT_NODE != nodeType)
+ && (DTM.DOCUMENT_FRAGMENT_NODE != nodeType))
+ {
+ // TODO: Process the use-attribute-sets stuff
+
+ if (DTM.ELEMENT_NODE == nodeType)
+ {
+ String ns = dtm.getNamespaceURI(child);
+ String localName = dtm.getLocalName(child);
+ String qname = dtm.getNodeNameX(child);
+
+ rth.startElement(ns, localName, qname, null);
+
+ if(null != ((ElemUse)t).getUseAttributeSets())
+ ((ElemUse)t).applyAttrSets(transformer, sroot);
+
+ rth.processNSDecls(child, nodeType, dtm);
+ transformer.executeChildTemplates(t, true);
+
+ rth.endElement(ns, localName, qname);
+ }
+ else
+ {
+ ClonerToResultTree.cloneToResultTree(child, nodeType,
+ dtm, rth, false);
+ if (TransformerImpl.S_DEBUG)
+ transformer.getTraceManager().fireTraceEvent(t);
+ }
+ }
+ else
+ {
+ if (TransformerImpl.S_DEBUG)
+ transformer.getTraceManager().fireTraceEvent(t);
+
+ super.execute(transformer);
+ transformer.executeChildTemplates(t, true);
+ }
+ break;
+ default :
t.execute(transformer);
}
}
- reMarkParams(xctxt);
+ if(savedSearchStart > 0)
+ reMarkParams(xctxt);
}
finally
{
- xctxt.popCurrentNode();
- if(needToFindTemplate)
+ if (needToFindTemplate)
transformer.popCurrentMatched();
if (check)
@@ -485,17 +559,27 @@
}
finally
{
- xctxt.setSAXLocator(savedLocator);
- xctxt.popContextNodeList();
- transformer.popElemTemplateElement();
- popParams(xctxt, savedSearchStart);
+ if (didSetVars)
+ {
+ xctxt.setSAXLocator(savedLocator);
+ xctxt.popContextNodeList();
+ transformer.popElemTemplateElement();
+ popParams(xctxt, savedSearchStart);
+ }
+
// if(null != sourceNodes)
// sourceNodes.detach();
}
}
- catch(SAXException se)
+ catch (SAXException se)
{
transformer.getErrorListener().fatalError(new TransformerException(se));
+ }
+ finally
+ {
+ xctxt.popCurrentExpressionNode();
+ xctxt.popCurrentNode();
+ sourceNodes.detach();
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org