elemforeach.java

来自「java jdk 1.4的源码」· Java 代码 · 共 556 行 · 第 1/2 页

JAVA
556
字号
  public String getNodeName()  {    return Constants.ELEMNAME_FOREACH_STRING;  }  /**   * 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  {    transformer.pushCurrentTemplateRuleIsNull(true);        if (TransformerImpl.S_DEBUG)      transformer.getTraceManager().fireTraceEvent(this);    try    {      transformSelectedNodes(transformer);    }    finally    {      if (TransformerImpl.S_DEBUG)	    transformer.getTraceManager().fireTraceEndEvent(this);       transformer.popCurrentTemplateRuleIsNull();    }  }  /**   * Get template element associated with this   *   *   * @return template element associated with this (itself)   */  protected ElemTemplateElement getTemplateMatch()  {    return this;  }  /**   * Sort given nodes   *   *   * @param xctxt The XPath runtime state for the sort.   * @param keys Vector of sort keyx   * @param sourceNodes Iterator of nodes to sort   *   * @return iterator of sorted nodes   *   * @throws TransformerException   */  public DTMIterator sortNodes(          XPathContext xctxt, Vector keys, DTMIterator sourceNodes)            throws TransformerException  {    NodeSorter sorter = new NodeSorter(xctxt);    sourceNodes.setShouldCacheNodes(true);    sourceNodes.runTo(-1);    xctxt.pushContextNodeList(sourceNodes);    try    {      sorter.sort(sourceNodes, keys, xctxt);      sourceNodes.setCurrentPos(0);    }    finally    {      xctxt.popContextNodeList();    }    return sourceNodes;  }  /**   * <meta name="usage" content="advanced"/>   * Perform a query if needed, and call transformNode for each child.   *   * @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)          throws TransformerException  {    final XPathContext xctxt = transformer.getXPathContext();    final int sourceNode = xctxt.getCurrentNode();    DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt,            sourceNode);    try    {      final Vector keys = (m_sortElems == null)              ? null              : transformer.processSortKeys(this, sourceNode);      // Sort if we need to.      if (null != keys)        sourceNodes = sortNodes(xctxt, keys, sourceNodes);      if (TransformerImpl.S_DEBUG)      {        transformer.getTraceManager().fireSelectedEvent(sourceNode, this,                "select", new XPath(m_selectExpression),                new org.apache.xpath.objects.XNodeSet(sourceNodes));      }      final ResultTreeHandler rth = transformer.getResultTreeHandler();      ContentHandler chandler = rth.getContentHandler();      xctxt.pushCurrentNode(DTM.NULL);      IntStack currentNodes = xctxt.getCurrentNodeStack();      xctxt.pushCurrentExpressionNode(DTM.NULL);      IntStack currentExpressionNodes = xctxt.getCurrentExpressionNodeStack();      xctxt.pushSAXLocatorNull();      xctxt.pushContextNodeList(sourceNodes);      transformer.pushElemTemplateElement(null);      // pushParams(transformer, xctxt);      // 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()))      {        currentNodes.setTop(child);        currentExpressionNodes.setTop(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 = dtm.getNodeType(child);         // Fire a trace event for the template.        if (TransformerImpl.S_DEBUG)        {           transformer.getTraceManager().fireTraceEvent(this);        }        // And execute the child templates.        // Loop through the children of the template, calling execute on         // each of them.        for (ElemTemplateElement t = this.m_firstChild; t != null;             t = t.m_nextSibling)        {          xctxt.setSAXLocator(t);          transformer.setCurrentElement(t);          t.execute(transformer);        }                if (TransformerImpl.S_DEBUG)        {         // We need to make sure an old current element is not           // on the stack.  See TransformerImpl#getElementCallstack.          transformer.setCurrentElement(null);          transformer.getTraceManager().fireTraceEndEvent(this);        }	 	// KLUGE: Implement <?xalan:doc_cache_off?> 	 	// ASSUMPTION: This will be set only when the XPath was indeed	 	// a call to the Document() function. Calling it in other	 	// situations is likely to fry Xalan.	 	//	 	// %REVIEW% We need a MUCH cleaner solution -- one that will	 	// handle cleaning up after document() and getDTM() in other		// contexts. The whole SourceTreeManager mechanism should probably	 	// be moved into DTMManager rather than being explicitly invoked in	 	// FuncDocument and here.	 	if(m_doc_cache_off)		{	 	  if(DEBUG)	 	    System.out.println("JJK***** CACHE RELEASE *****\n"+				       "\tdtm="+dtm.getDocumentBaseURI());	  	// NOTE: This will work because this is _NOT_ a shared DTM, and thus has	  	// only a single Document node. If it could ever be an RTF or other	 	// shared DTM, this would require substantial rework.	 	  xctxt.getSourceTreeManager().removeDocumentFromCache(dtm.getDocument());	 	  xctxt.release(dtm,false);	 	}      }    }    finally    {      if (TransformerImpl.S_DEBUG)        transformer.getTraceManager().fireSelectedEndEvent(sourceNode, this,                "select", new XPath(m_selectExpression),                new org.apache.xpath.objects.XNodeSet(sourceNodes));      xctxt.popSAXLocator();      xctxt.popContextNodeList();      transformer.popElemTemplateElement();      xctxt.popCurrentExpressionNode();      xctxt.popCurrentNode();      sourceNodes.detach();    }  }  /**   * Add a child to the child list.   * <!ELEMENT xsl:apply-templates (xsl:sort|xsl:with-param)*>   * <!ATTLIST xsl:apply-templates   *   select %expr; "node()"   *   mode %qname; #IMPLIED   * >   *   * @param newChild Child to add to child list   *   * @return Child just added to child list   */  public ElemTemplateElement appendChild(ElemTemplateElement newChild)  {    int type = ((ElemTemplateElement) newChild).getXSLToken();    if (Constants.ELEMNAME_SORT == type)    {      setSortElem((ElemSort) newChild);      return newChild;    }    else      return super.appendChild(newChild);  }    /**   * Call the children visitors.   * @param visitor The visitor whose appropriate method will be called.   */  public void callChildVisitors(XSLTVisitor visitor, boolean callAttributes)  {  	if(callAttributes && (null != m_selectExpression))  		m_selectExpression.callVisitors(this, visitor);  		    int length = getSortElemCount();    for (int i = 0; i < length; i++)    {      getSortElem(i).callVisitors(visitor);    }    super.callChildVisitors(visitor, callAttributes);  }  /**   * @see ExpressionOwner#getExpression()   */  public Expression getExpression()  {    return m_selectExpression;  }  /**   * @see ExpressionOwner#setExpression(Expression)   */  public void setExpression(Expression exp)  {  	exp.exprSetParent(this);  	m_selectExpression = exp;  }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?