📄 steppattern.java
字号:
DTM dtm = xctxt.getDTM(context); int parent = dtm.getParent(context); try { DTMAxisTraverser traverser = dtm.getAxisTraverser(Axis.CHILD); for (int child = traverser.first(parent); DTM.NULL != child; child = traverser.next(parent, child)) { try { xctxt.pushCurrentNode(child); if (NodeTest.SCORE_NONE != super.execute(xctxt, child)) { boolean pass = true; try { xctxt.pushSubContextList(this); for (int i = 0; i < predPos; i++) { xctxt.pushPredicatePos(i); try { XObject pred = m_predicates[i].execute(xctxt); try { if (XObject.CLASS_NUMBER == pred.getType()) { if ((pos + 1) != (int) pred.numWithSideEffects()) { pass = false; break; } } else if (!pred.boolWithSideEffects()) { pass = false; break; } } finally { pred.detach(); } } finally { xctxt.popPredicatePos(); } } } finally { xctxt.popSubContextList(); } if (pass) pos++; if (!findLast && child == context) { return pos; } } } finally { xctxt.popCurrentNode(); } } } catch (javax.xml.transform.TransformerException se) { // TODO: should keep throw sax exception... throw new java.lang.RuntimeException(se.getMessage()); } return pos; } /** * Get the proximity position index of the current node based on this * node test. * * * @param xctxt XPath runtime context. * * @return the proximity position index of the current node based on the * node test. */ public int getProximityPosition(XPathContext xctxt) { return getProximityPosition(xctxt, xctxt.getPredicatePos(), false); } /** * Get the count of the nodes that match the test, which is the proximity * position of the last node that can pass this test in the sub context * selection. In XSLT 1-based indexing, this count is the index of the last * node. * * * @param xctxt XPath runtime context. * * @return the count of the nodes that match the test. */ public int getLastPos(XPathContext xctxt) { return getProximityPosition(xctxt, xctxt.getPredicatePos(), true); } /** * Execute the match pattern step relative to another step. * * * @param xctxt The XPath runtime context. * @param dtm The DTM of the current node. * @param currentNode The current node context. * * @return {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NODETEST}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NONE}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NSWILD}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_QNAME}, or * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_OTHER}. * * @throws javax.xml.transform.TransformerException */ protected final XObject executeRelativePathPattern( XPathContext xctxt, DTM dtm, int currentNode) throws javax.xml.transform.TransformerException { XObject score = NodeTest.SCORE_NONE; int context = currentNode; DTMAxisTraverser traverser; traverser = dtm.getAxisTraverser(m_axis); for (int relative = traverser.first(context); DTM.NULL != relative; relative = traverser.next(context, relative)) { try { xctxt.pushCurrentNode(relative); score = execute(xctxt); if (score != NodeTest.SCORE_NONE) break; } finally { xctxt.popCurrentNode(); } } return score; } /** * Execute the predicates on this step to determine if the current node * should be filtered or accepted. * * @param xctxt The XPath runtime context. * @param dtm The DTM of the current node. * @param currentNode The current node context. * * @return true if the node should be accepted, false otherwise. * * @throws javax.xml.transform.TransformerException */ protected final boolean executePredicates( XPathContext xctxt, DTM dtm, int currentNode) throws javax.xml.transform.TransformerException { boolean result = true; boolean positionAlreadySeen = false; int n = getPredicateCount(); try { xctxt.pushSubContextList(this); for (int i = 0; i < n; i++) { xctxt.pushPredicatePos(i); try { XObject pred = m_predicates[i].execute(xctxt); try { if (XObject.CLASS_NUMBER == pred.getType()) { int pos = (int) pred.num(); if (positionAlreadySeen) { result = (pos == 1); break; } else { positionAlreadySeen = true; if (!checkProximityPosition(xctxt, i, dtm, currentNode, pos)) { result = false; break; } } } else if (!pred.boolWithSideEffects()) { result = false; break; } } finally { pred.detach(); } } finally { xctxt.popPredicatePos(); } } } finally { xctxt.popSubContextList(); } return result; } /** * Get the string represenentation of this step for diagnostic purposes. * * * @return A string representation of this step, built by reverse-engineering * the contained info. */ public String toString() { StringBuffer buf = new StringBuffer(); for (StepPattern pat = this; pat != null; pat = pat.m_relativePathPattern) { if (pat != this) buf.append("/"); buf.append(Axis.getNames(pat.m_axis)); buf.append("::"); if (0x000005000 == pat.m_whatToShow) { buf.append("doc()"); } else if (DTMFilter.SHOW_BYFUNCTION == pat.m_whatToShow) { buf.append("function()"); } else if (DTMFilter.SHOW_ALL == pat.m_whatToShow) { buf.append("node()"); } else if (DTMFilter.SHOW_TEXT == pat.m_whatToShow) { buf.append("text()"); } else if (DTMFilter.SHOW_PROCESSING_INSTRUCTION == pat.m_whatToShow) { buf.append("processing-instruction("); if (null != pat.m_name) { buf.append(pat.m_name); } buf.append(")"); } else if (DTMFilter.SHOW_COMMENT == pat.m_whatToShow) { buf.append("comment()"); } else if (null != pat.m_name) { if (DTMFilter.SHOW_ATTRIBUTE == pat.m_whatToShow) { buf.append("@"); } if (null != pat.m_namespace) { buf.append("{"); buf.append(pat.m_namespace); buf.append("}"); } buf.append(pat.m_name); } else if (DTMFilter.SHOW_ATTRIBUTE == pat.m_whatToShow) { buf.append("@"); } else if ((DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT) == pat.m_whatToShow) { buf.append("doc-root()"); } else { buf.append("?" + Integer.toHexString(pat.m_whatToShow)); } if (null != pat.m_predicates) { for (int i = 0; i < pat.m_predicates.length; i++) { buf.append("["); buf.append(pat.m_predicates[i]); buf.append("]"); } } } return buf.toString(); } /** Set to true to send diagnostics about pattern matches to the consol. */ private static final boolean DEBUG_MATCHES = false; /** * Get the match score of the given node. * * @param xctxt The XPath runtime context. * @param context The node to be tested. * * @return {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NODETEST}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NONE}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_NSWILD}, * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_QNAME}, or * {@link com.sun.org.apache.xpath.internal.patterns.NodeTest#SCORE_OTHER}. * * @throws javax.xml.transform.TransformerException */ public double getMatchScore(XPathContext xctxt, int context) throws javax.xml.transform.TransformerException { xctxt.pushCurrentNode(context); xctxt.pushCurrentExpressionNode(context); try { XObject score = execute(xctxt); return score.num(); } finally { xctxt.popCurrentNode(); xctxt.popCurrentExpressionNode(); } // return XPath.MATCH_SCORE_NONE; } /** * Set the axis that this step should follow. * * * @param axis The Axis for this test, one of of Axes.ANCESTORORSELF, etc. */ public void setAxis(int axis) { m_axis = axis; } /** * Get the axis that this step follows. * * * @return The Axis for this test, one of of Axes.ANCESTORORSELF, etc. */ public int getAxis() { return m_axis; } 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(StepPattern.this); m_predicates[m_index] = exp; } } /** * @see com.sun.org.apache.xpath.internal.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor) */ public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) { if(visitor.visitMatchPattern(owner, this)) { callSubtreeVisitors(visitor); } } /** * Call the visitors on the subtree. Factored out from callVisitors * so it may be called by derived classes. */ protected void callSubtreeVisitors(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); } } } if (null != m_relativePathPattern) { m_relativePathPattern.callVisitors(this, visitor); } } /** * @see ExpressionOwner#getExpression() */ public Expression getExpression() { return m_relativePathPattern; } /** * @see ExpressionOwner#setExpression(Expression) */ public void setExpression(Expression exp) { exp.exprSetParent(this); m_relativePathPattern = (StepPattern)exp; } /** * @see Expression#deepEquals(Expression) */ public boolean deepEquals(Expression expr) { if(!super.deepEquals(expr)) return false; StepPattern sp = (StepPattern)expr; if (null != m_predicates) { int n = m_predicates.length; if ((null == sp.m_predicates) || (sp.m_predicates.length != n)) return false; for (int i = 0; i < n; i++) { if (!m_predicates[i].deepEquals(sp.m_predicates[i])) return false; } } else if (null != sp.m_predicates) return false; if(null != m_relativePathPattern) { if(!m_relativePathPattern.deepEquals(sp.m_relativePathPattern)) return false; } else if(sp.m_relativePathPattern != null) return false; return true; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -