📄 unionpathiterator.java
字号:
return clone; } /** * Create a new location path iterator. * * @param compiler The Compiler which is creating * this expression. * @param opPos The position of this iterator in the * * @return New location path iterator. * * @throws javax.xml.transform.TransformerException */ protected LocPathIterator createDTMIterator( Compiler compiler, int opPos) throws javax.xml.transform.TransformerException { LocPathIterator lpi = (LocPathIterator)WalkerFactory.newDTMIterator(compiler, opPos, (compiler.getLocationPathDepth() <= 0)); return lpi; } /** * Initialize the location path iterators. Recursive. * * @param compiler The Compiler which is creating * this expression. * @param opPos The position of this iterator in the * opcode list from the compiler. * @param count The insert position of the iterator. * * @throws javax.xml.transform.TransformerException */ protected void loadLocationPaths(Compiler compiler, int opPos, int count) throws javax.xml.transform.TransformerException { // TODO: Handle unwrapped FilterExpr int steptype = compiler.getOp(opPos); if (steptype == OpCodes.OP_LOCATIONPATH) { loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1); m_exprs[count] = createDTMIterator(compiler, opPos); m_exprs[count].exprSetParent(this); } else { // Have to check for unwrapped functions, which the LocPathIterator // doesn't handle. switch (steptype) { case OpCodes.OP_VARIABLE : case OpCodes.OP_EXTFUNCTION : case OpCodes.OP_FUNCTION : case OpCodes.OP_GROUP : loadLocationPaths(compiler, compiler.getNextOpPos(opPos), count + 1); WalkingIterator iter = new WalkingIterator(compiler.getNamespaceContext()); iter.exprSetParent(this); if(compiler.getLocationPathDepth() <= 0) iter.setIsTopLevel(true); iter.m_firstWalker = new com.sun.org.apache.xpath.internal.axes.FilterExprWalker(iter); iter.m_firstWalker.init(compiler, opPos, steptype); m_exprs[count] = iter; break; default : m_exprs = new LocPathIterator[count]; } } } /** * Returns the next node in the set and advances the position of the * iterator in the set. After a DTMIterator is created, the first call * to nextNode() returns the first node in the set. * @return The next <code>Node</code> in the set being iterated over, or * <code>null</code> if there are no more members in that set. */ public int nextNode() { if(m_foundLast) return DTM.NULL; // Loop through the iterators getting the current fetched // node, and get the earliest occuring in document order int earliestNode = DTM.NULL; if (null != m_iterators) { int n = m_iterators.length; int iteratorUsed = -1; for (int i = 0; i < n; i++) { int node = m_iterators[i].getCurrentNode(); if (DTM.NULL == node) continue; else if (DTM.NULL == earliestNode) { iteratorUsed = i; earliestNode = node; } else { if (node == earliestNode) { // Found a duplicate, so skip past it. m_iterators[i].nextNode(); } else { DTM dtm = getDTM(node); if (dtm.isNodeAfter(node, earliestNode)) { iteratorUsed = i; earliestNode = node; } } } } if (DTM.NULL != earliestNode) { m_iterators[iteratorUsed].nextNode(); incrementCurrentPos(); } else m_foundLast = true; } m_lastFetched = earliestNode; return earliestNode; } /** * This function is used to fixup variables from QNames to stack frame * indexes at stylesheet build time. * @param vars List of QNames that correspond to variables. This list * should be searched backwards for the first qualified name that * corresponds to the variable reference qname. The position of the * QName in the vector from the start of the vector will be its position * in the stack frame (but variables above the globalsTop value will need * to be offset to the current stack frame). */ public void fixupVariables(java.util.Vector vars, int globalsSize) { for (int i = 0; i < m_exprs.length; i++) { m_exprs[i].fixupVariables(vars, globalsSize); } } /** * The location path iterators, one for each * <a href="http://www.w3.org/TR/xpath#NT-LocationPath">location * path</a> contained in the union expression. * @serial */ protected LocPathIterator[] m_exprs; /** * The location path iterators, one for each * <a href="http://www.w3.org/TR/xpath#NT-LocationPath">location * path</a> contained in the union expression. * @serial */ protected DTMIterator[] m_iterators; /** * Returns the axis being iterated, if it is known. * * @return Axis.CHILD, etc., or -1 if the axis is not known or is of multiple * types. */ public int getAxis() { // Could be smarter. return -1; } class iterOwner implements ExpressionOwner { int m_index; iterOwner(int index) { m_index = index; } /** * @see ExpressionOwner#getExpression() */ public Expression getExpression() { return m_exprs[m_index]; } /** * @see ExpressionOwner#setExpression(Expression) */ public void setExpression(Expression exp) { if(!(exp instanceof LocPathIterator)) { // Yuck. Need FilterExprIter. Or make it so m_exprs can be just // plain expressions? WalkingIterator wi = new WalkingIterator(getPrefixResolver()); FilterExprWalker few = new FilterExprWalker(wi); wi.setFirstWalker(few); few.setInnerExpression(exp); wi.exprSetParent(UnionPathIterator.this); few.exprSetParent(wi); exp.exprSetParent(few); exp = wi; } else exp.exprSetParent(UnionPathIterator.this); m_exprs[m_index] = (LocPathIterator)exp; } } /** * @see com.sun.org.apache.xpath.internal.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor) */ public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) { if(visitor.visitUnionPath(owner, this)) { if(null != m_exprs) { int n = m_exprs.length; for(int i = 0; i < n; i++) { m_exprs[i].callVisitors(new iterOwner(i), visitor); } } } } /** * @see Expression#deepEquals(Expression) */ public boolean deepEquals(Expression expr) { if (!super.deepEquals(expr)) return false; UnionPathIterator upi = (UnionPathIterator) expr; if (null != m_exprs) { int n = m_exprs.length; if((null == upi.m_exprs) || (upi.m_exprs.length != n)) return false; for (int i = 0; i < n; i++) { if(!m_exprs[i].deepEquals(upi.m_exprs[i])) return false; } } else if (null != upi.m_exprs) { return false; } return true; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -