public AncestorQualifiedPattern(Pattern base, Pattern upper, byte axis) { this.basePattern = base; this.upperPattern = upper; this.upwardsAxis = axis; adoptChildExpression(base); adoptChildExpression(upper); }
/** * Determine whether the pattern matches a given item. * * @param item the item to be tested * @return true if the pattern matches, else false */ public boolean matches(Item<?> item, XPathContext context) throws XPathException { return item instanceof NodeInfo && matchesBeneathAnchor((NodeInfo) item, null, context); }
/** * Determine whether this pattern matches a given Node within the subtree rooted at a given * anchor node. This method is used when the pattern is used for streaming. * * @param node The NodeInfo representing the Element or other node to be tested against the Pattern * @param anchor The anchor node, which must match any AnchorPattern subpattern * @param context The dynamic context. Only relevant if the pattern * uses variables, or contains calls on functions such as document() or key(). * @return true if the node matches the Pattern, false otherwise */ public boolean matchesBeneathAnchor(NodeInfo node, NodeInfo anchor, XPathContext context) throws XPathException { if (testUpperPatternFirst) { return matchesUpperPattern(node, anchor, context) && basePattern.matches(node, context); } else { return basePattern.matchesBeneathAnchor(node, anchor, context) && matchesUpperPattern(node, anchor, context); } }
/** * Copy a pattern. This makes a deep copy. * * @return the copy of the original pattern * @param rebindings variables that need to be re-bound */ /*@NotNull*/ public Pattern copy(RebindingMap rebindings) { AncestorQualifiedPattern n = new AncestorQualifiedPattern(basePattern.copy(rebindings), upperPattern.copy(rebindings), upwardsAxis); ExpressionTool.copyLocationInfo(this, n); return n; }
public void export(ExpressionPresenter presenter) throws XPathException { presenter.startElement("p.withUpper"); presenter.emitAttribute("axis", AxisInfo.axisName[getUpwardsAxis()]); presenter.emitAttribute("upFirst", ""+ testUpperPatternFirst); basePattern.export(presenter); upperPattern.export(presenter); presenter.endElement(); }
/** * Get the immediate sub-expressions of this expression, with information about the relationship * of each expression to its parent expression. Default implementation * works off the results of iterateSubExpressions() * <p>If the expression is a Callable, then it is required that the order of the operands * returned by this function is the same as the order of arguments supplied to the corresponding * call() method.</p> * * @return an iterator containing the sub-expressions of this expression */ @Override public Iterable<Operand> operands() { return operandList( new Operand(this, upperPattern, OperandRole.SAME_FOCUS_ACTION), new Operand(this, basePattern, OperandRole.SAME_FOCUS_ACTION)); }
private boolean matchesUpperPattern(NodeInfo node, NodeInfo anchor, XPathContext context) throws XPathException { switch (upwardsAxis) { case AxisInfo.SELF: return upperPattern.matchesBeneathAnchor(node, anchor, context); case AxisInfo.PARENT: NodeInfo par = node.getParent(); return par != null && upperPattern.matchesBeneathAnchor(par, anchor, context); case AxisInfo.ANCESTOR: { NodeInfo anc = node.getParent(); return hasMatchingAncestor(anchor, anc, context); } case AxisInfo.ANCESTOR_OR_SELF: { return hasMatchingAncestor(anchor, node, context); } default: throw new XPathException("Unsupported axis " + AxisInfo.axisName[upwardsAxis] + " in pattern"); } }
/** * Convert the pattern to a typed pattern, in which an element name is treated as * schema-element(N) * * @param val either "strict" or "lax" depending on the value of xsl:mode/@typed * @return either the original pattern unchanged, or a new pattern as the result of the * conversion * @throws net.sf.saxon.trans.XPathException if the pattern cannot be converted */ @Override public Pattern convertToTypedPattern(String val) throws XPathException { if (upperPattern.getUType().equals(UType.DOCUMENT)) { // suggests a pattern starting with a leading slash Pattern b2 = basePattern.convertToTypedPattern(val); if (b2 == basePattern) { return this; } else { return new AncestorQualifiedPattern(b2, upperPattern, upwardsAxis); } } else { Pattern u2 = upperPattern.convertToTypedPattern(val); if (u2 == upperPattern) { return this; } else { return new AncestorQualifiedPattern(basePattern, u2, upwardsAxis); } } }
public void export(ExpressionPresenter presenter) throws XPathException { presenter.startElement("p.withUpper"); presenter.emitAttribute("axis", AxisInfo.axisName[getUpwardsAxis()]); presenter.emitAttribute("upFirst", ""+ testUpperPatternFirst); basePattern.export(presenter); upperPattern.export(presenter); presenter.endElement(); }
/** * Get the immediate sub-expressions of this expression, with information about the relationship * of each expression to its parent expression. Default implementation * works off the results of iterateSubExpressions() * <p>If the expression is a Callable, then it is required that the order of the operands * returned by this function is the same as the order of arguments supplied to the corresponding * call() method.</p> * * @return an iterator containing the sub-expressions of this expression */ @Override public Iterable<Operand> operands() { return operandList( new Operand(this, upperPattern, OperandRole.SAME_FOCUS_ACTION), new Operand(this, basePattern, OperandRole.SAME_FOCUS_ACTION)); }
private boolean matchesUpperPattern(NodeInfo node, NodeInfo anchor, XPathContext context) throws XPathException { switch (upwardsAxis) { case AxisInfo.SELF: return upperPattern.matchesBeneathAnchor(node, anchor, context); case AxisInfo.PARENT: NodeInfo par = node.getParent(); return par != null && upperPattern.matchesBeneathAnchor(par, anchor, context); case AxisInfo.ANCESTOR: { NodeInfo anc = node.getParent(); return hasMatchingAncestor(anchor, anc, context); } case AxisInfo.ANCESTOR_OR_SELF: { return hasMatchingAncestor(anchor, node, context); } default: throw new XPathException("Unsupported axis " + AxisInfo.axisName[upwardsAxis] + " in pattern"); } }
/** * Convert the pattern to a typed pattern, in which an element name is treated as * schema-element(N) * * @param val either "strict" or "lax" depending on the value of xsl:mode/@typed * @return either the original pattern unchanged, or a new pattern as the result of the * conversion * @throws net.sf.saxon.trans.XPathException if the pattern cannot be converted */ @Override public Pattern convertToTypedPattern(String val) throws XPathException { if (upperPattern.getUType().equals(UType.DOCUMENT)) { // suggests a pattern starting with a leading slash Pattern b2 = basePattern.convertToTypedPattern(val); if (b2 == basePattern) { return this; } else { return new AncestorQualifiedPattern(b2, upperPattern, upwardsAxis); } } else { Pattern u2 = upperPattern.convertToTypedPattern(val); if (u2 == upperPattern) { return this; } else { return new AncestorQualifiedPattern(basePattern, u2, upwardsAxis); } } }
public AncestorQualifiedPattern(Pattern base, Pattern upper, byte axis) { this.basePattern = base; this.upperPattern = upper; this.upwardsAxis = axis; adoptChildExpression(base); adoptChildExpression(upper); }
/** * Determine whether the pattern matches a given item. * * @param item the item to be tested * @return true if the pattern matches, else false */ public boolean matches(Item<?> item, XPathContext context) throws XPathException { return item instanceof NodeInfo && matchesBeneathAnchor((NodeInfo) item, null, context); }
/** * Determine whether this pattern matches a given Node within the subtree rooted at a given * anchor node. This method is used when the pattern is used for streaming. * * @param node The NodeInfo representing the Element or other node to be tested against the Pattern * @param anchor The anchor node, which must match any AnchorPattern subpattern * @param context The dynamic context. Only relevant if the pattern * uses variables, or contains calls on functions such as document() or key(). * @return true if the node matches the Pattern, false otherwise */ public boolean matchesBeneathAnchor(NodeInfo node, NodeInfo anchor, XPathContext context) throws XPathException { if (testUpperPatternFirst) { return matchesUpperPattern(node, anchor, context) && basePattern.matches(node, context); } else { return basePattern.matchesBeneathAnchor(node, anchor, context) && matchesUpperPattern(node, anchor, context); } }
/** * Copy a pattern. This makes a deep copy. * * @return the copy of the original pattern * @param rebindings variables that need to be re-bound */ /*@NotNull*/ public Pattern copy(RebindingMap rebindings) { AncestorQualifiedPattern n = new AncestorQualifiedPattern(basePattern.copy(rebindings), upperPattern.copy(rebindings), upwardsAxis); ExpressionTool.copyLocationInfo(this, n); return n; }
headPattern = head.toPattern(config); return new AncestorQualifiedPattern(tailPattern, headPattern, axis);
headPattern = head.toPattern(config); return new AncestorQualifiedPattern(tailPattern, headPattern, axis);
headPattern = head.toPattern(config); return new AncestorQualifiedPattern(tailPattern, headPattern, axis);