📄 predicatednodetest.java
字号:
// System.out.println("nPredicates: "+nPredicates); if (nPredicates == 0) return true; PrefixResolver savedResolver = xctxt.getNamespaceContext(); try { m_predicateIndex = 0; xctxt.pushSubContextList(this); xctxt.pushNamespaceContext(m_lpi.getPrefixResolver()); xctxt.pushCurrentNode(context); for (int i = 0; i < nPredicates; i++) { // System.out.println("Executing predicate expression - waiting count: "+m_lpi.getWaitingCount()); XObject pred = m_predicates[i].execute(xctxt); // System.out.println("\nBack from executing predicate expression - waiting count: "+m_lpi.getWaitingCount()); // System.out.println("pred.getType(): "+pred.getType()); if (XObject.CLASS_NUMBER == pred.getType()) { if (DEBUG_PREDICATECOUNTING) { System.out.flush(); System.out.println("\n===== start predicate count ========"); System.out.println("m_predicateIndex: " + m_predicateIndex); // System.out.println("getProximityPosition(m_predicateIndex): " // + getProximityPosition(m_predicateIndex)); System.out.println("pred.num(): " + pred.num()); } int proxPos = this.getProximityPosition(m_predicateIndex); int predIndex = (int) pred.num(); if (proxPos != predIndex) { if (DEBUG_PREDICATECOUNTING) { System.out.println("\nnode context: "+nodeToString(context)); System.out.println("index predicate is false: "+proxPos); System.out.println("\n===== end predicate count ========"); } return false; } else if (DEBUG_PREDICATECOUNTING) { System.out.println("\nnode context: "+nodeToString(context)); System.out.println("index predicate is true: "+proxPos); System.out.println("\n===== end predicate count ========"); } // If there is a proximity index that will not change during the // course of itteration, then we know there can be no more true // occurances of this predicate, so flag that we're done after // this. // // bugzilla 14365 // We can't set m_foundLast = true unless we're sure that -all- // remaining parameters are stable, or else last() fails. Fixed so // only sets m_foundLast if on the last predicate if(m_predicates[i].isStableNumber() && i == nPredicates - 1) { m_foundLast = true; } } else if (!pred.bool()) return false; countProximityPosition(++m_predicateIndex); } } finally { xctxt.popCurrentNode(); xctxt.popNamespaceContext(); xctxt.popSubContextList(); m_predicateIndex = -1; } return true; } /** * 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) { super.fixupVariables(vars, globalsSize); int nPredicates = getPredicateCount(); for (int i = 0; i < nPredicates; i++) { m_predicates[i].fixupVariables(vars, globalsSize); } } /** * Diagnostics. * * @param n Node to give diagnostic information about, or null. * * @return Informative string about the argument. */ protected String nodeToString(int n) { if(DTM.NULL != n) { DTM dtm = m_lpi.getXPathContext().getDTM(n); return dtm.getNodeName(n) + "{" + (n+1) + "}"; } else { return "null"; } } //=============== NodeFilter Implementation =============== /** * Test whether a specified node is visible in the logical view of a * TreeWalker or NodeIterator. This function will be called by the * implementation of TreeWalker and NodeIterator; it is not intended to * be called directly from user code. * @param n The node to check to see if it passes the filter or not. * @return a constant to determine whether the node is accepted, * rejected, or skipped, as defined above . */ public short acceptNode(int n) { XPathContext xctxt = m_lpi.getXPathContext(); try { xctxt.pushCurrentNode(n); XObject score = execute(xctxt, n); // System.out.println("\n::acceptNode - score: "+score.num()+"::"); if (score != NodeTest.SCORE_NONE) { if (getPredicateCount() > 0) { countProximityPosition(0); if (!executePredicates(n, xctxt)) return DTMIterator.FILTER_SKIP; } return DTMIterator.FILTER_ACCEPT; } } catch (javax.xml.transform.TransformerException se) { // TODO: Fix this. throw new RuntimeException(se.getMessage()); } finally { xctxt.popCurrentNode(); } return DTMIterator.FILTER_SKIP; } /** * Get the owning location path iterator. * * @return the owning location path iterator, which should not be null. */ public LocPathIterator getLocPathIterator() { return m_lpi; } /** * Set the location path iterator owner for this walker. Besides * initialization, this function is called during cloning operations. * * @param li non-null reference to the owning location path iterator. */ public void setLocPathIterator(LocPathIterator li) { m_lpi = li; if(this != li) li.exprSetParent(this); } /** * Tell if this expression or it's subexpressions can traverse outside * the current subtree. * * @return true if traversal outside the context node's subtree can occur. */ public boolean canTraverseOutsideSubtree() { int n = getPredicateCount(); for (int i = 0; i < n; i++) { if(getPredicate(i).canTraverseOutsideSubtree()) return true; } return false; } /** * This will traverse the heararchy, calling the visitor for * each member. If the called visitor method returns * false, the subtree should not be called. * * @param visitor The visitor whose appropriate method will be called. */ public void callPredicateVisitors(XPathVisitor visitor) { if (null != m_predicates) { int n = m_predicates.length; for (int i = 0; i < n; i++) { ExpressionOwner predOwner = new PredOwner(i); if (visitor.visitPredicate(predOwner, m_predicates[i])) { m_predicates[i].callVisitors(predOwner, visitor); } } } } /** * @see Expression#deepEquals(Expression) */ public boolean deepEquals(Expression expr) { if (!super.deepEquals(expr)) return false; PredicatedNodeTest pnt = (PredicatedNodeTest) expr; if (null != m_predicates) { int n = m_predicates.length; if ((null == pnt.m_predicates) || (pnt.m_predicates.length != n)) return false; for (int i = 0; i < n; i++) { if (!m_predicates[i].deepEquals(pnt.m_predicates[i])) return false; } } else if (null != pnt.m_predicates) return false; return true; } /** This is true if nextNode returns null. */ transient protected boolean m_foundLast = false; /** The owning location path iterator. * @serial */ protected LocPathIterator m_lpi; /** * Which predicate we are executing. */ transient int m_predicateIndex = -1; /** The list of predicate expressions. Is static and does not need * to be deep cloned. * @serial */ private Expression[] m_predicates; /** * An array of counts that correspond to the number * of predicates the step contains. */ transient protected int[] m_proximityPositions; /** If true, diagnostic messages about predicate execution will be posted. */ static final boolean DEBUG_PREDICATECOUNTING = false; class PredOwner implements ExpressionOwner { int m_index; PredOwner(int index) { m_index = index; } /** * @see ExpressionOwner#getExpression() */ public Expression getExpression() { return m_predicates[m_index]; } /** * @see ExpressionOwner#setExpression(Expression) */ public void setExpression(Expression exp) { exp.exprSetParent(PredicatedNodeTest.this); m_predicates[m_index] = exp; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -