use of org.apache.xpath.objects.XNumber in project robovm by robovm.
the class WalkerFactory method loadSteps.
/**
* Read a <a href="http://www.w3.org/TR/xpath#location-paths">LocationPath</a>
* as a generalized match pattern. What this means is that the LocationPath
* is read backwards, as a test on a given node, to see if it matches the
* criteria of the selection, and ends up at the context node. Essentially,
* this is a backwards query from a given node, to find the context node.
* <p>So, the selection "foo/daz[2]" is, in non-abreviated expanded syntax,
* "self::node()/following-sibling::foo/child::daz[position()=2]".
* Taking this as a match pattern for a probable node, it works out to
* "self::daz/parent::foo[child::daz[position()=2 and isPrevStepNode()]
* precedingSibling::node()[isContextNodeOfLocationPath()]", adding magic
* isPrevStepNode and isContextNodeOfLocationPath operations. Predicates in
* the location path have to be executed by the following step,
* because they have to know the context of their execution.
*
* @param mpi The MatchPatternIterator to which the steps will be attached.
* @param compiler The compiler that holds the syntax tree/op map to
* construct from.
* @param stepOpCodePos The current op code position within the opmap.
* @param stepIndex The top-level step index withing the iterator.
*
* @return A StepPattern object, which may contain relative StepPatterns.
*
* @throws javax.xml.transform.TransformerException
*/
static StepPattern loadSteps(MatchPatternIterator mpi, Compiler compiler, int stepOpCodePos, int stepIndex) throws javax.xml.transform.TransformerException {
if (DEBUG_PATTERN_CREATION) {
System.out.println("================");
System.out.println("loadSteps for: " + compiler.getPatternString());
}
int stepType;
StepPattern step = null;
StepPattern firstStep = null, prevStep = null;
int analysis = analyze(compiler, stepOpCodePos, stepIndex);
while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos))) {
step = createDefaultStepPattern(compiler, stepOpCodePos, mpi, analysis, firstStep, prevStep);
if (null == firstStep) {
firstStep = step;
} else {
//prevStep.setNextWalker(step);
step.setRelativePathPattern(prevStep);
}
prevStep = step;
stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
if (stepOpCodePos < 0)
break;
}
int axis = Axis.SELF;
int paxis = Axis.SELF;
StepPattern tail = step;
for (StepPattern pat = step; null != pat; pat = pat.getRelativePathPattern()) {
int nextAxis = pat.getAxis();
//int nextPaxis = pat.getPredicateAxis();
pat.setAxis(axis);
// The predicate axis can't be moved!!! Test Axes103
// pat.setPredicateAxis(paxis);
// If we have an attribute or namespace axis that went up, then
// it won't find the attribute in the inverse, since the select-to-match
// axes are not invertable (an element is a parent of an attribute, but
// and attribute is not a child of an element).
// If we don't do the magic below, then "@*/ancestor-or-self::*" gets
// inverted for match to "self::*/descendant-or-self::@*/parent::node()",
// which obviously won't work.
// So we will rewrite this as:
// "self::*/descendant-or-self::*/attribute::*/parent::node()"
// Child has to be rewritten a little differently:
// select: "@*/parent::*"
// inverted match: "self::*/child::@*/parent::node()"
// rewrite: "self::*/attribute::*/parent::node()"
// Axes that go down in the select, do not have to have special treatment
// in the rewrite. The following inverted match will still not select
// anything.
// select: "@*/child::*"
// inverted match: "self::*/parent::@*/parent::node()"
// Lovely business, this.
// -sb
int whatToShow = pat.getWhatToShow();
if (whatToShow == DTMFilter.SHOW_ATTRIBUTE || whatToShow == DTMFilter.SHOW_NAMESPACE) {
int newAxis = (whatToShow == DTMFilter.SHOW_ATTRIBUTE) ? Axis.ATTRIBUTE : Axis.NAMESPACE;
if (isDownwardAxisOfMany(axis)) {
StepPattern attrPat = new StepPattern(whatToShow, pat.getNamespace(), pat.getLocalName(), //newAxis, pat.getPredicateAxis);
newAxis, // don't care about the predicate axis
0);
XNumber score = pat.getStaticScore();
pat.setNamespace(null);
pat.setLocalName(NodeTest.WILD);
attrPat.setPredicates(pat.getPredicates());
pat.setPredicates(null);
pat.setWhatToShow(DTMFilter.SHOW_ELEMENT);
StepPattern rel = pat.getRelativePathPattern();
pat.setRelativePathPattern(attrPat);
attrPat.setRelativePathPattern(rel);
attrPat.setStaticScore(score);
// inverseable.
if (Axis.PRECEDING == pat.getAxis())
pat.setAxis(Axis.PRECEDINGANDANCESTOR);
else if (Axis.DESCENDANT == pat.getAxis())
pat.setAxis(Axis.DESCENDANTORSELF);
pat = attrPat;
} else if (Axis.CHILD == pat.getAxis()) {
// In this case just change the axis.
// pat.setWhatToShow(whatToShow);
pat.setAxis(Axis.ATTRIBUTE);
}
}
axis = nextAxis;
//paxis = nextPaxis;
tail = pat;
}
if (axis < Axis.ALL) {
StepPattern selfPattern = new ContextMatchStepPattern(axis, paxis);
// We need to keep the new nodetest from affecting the score...
XNumber score = tail.getStaticScore();
tail.setRelativePathPattern(selfPattern);
tail.setStaticScore(score);
selfPattern.setStaticScore(score);
}
if (DEBUG_PATTERN_CREATION) {
System.out.println("Done loading steps: " + step.toString());
System.out.println("");
}
// start from last pattern?? //firstStep;
return step;
}
use of org.apache.xpath.objects.XNumber in project robovm by robovm.
the class FunctionPattern method execute.
/**
* Test a node to see if it matches the given node test.
*
* @param xctxt XPath runtime context.
*
* @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
* {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
* {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
* {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
* {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
*
* @throws javax.xml.transform.TransformerException
*/
public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
int context = xctxt.getCurrentNode();
DTMIterator nl = m_functionExpr.asIterator(xctxt, context);
XNumber score = SCORE_NONE;
if (null != nl) {
int n;
while (DTM.NULL != (n = nl.nextNode())) {
score = (n == context) ? SCORE_OTHER : SCORE_NONE;
if (score == SCORE_OTHER) {
context = n;
break;
}
}
nl.detach();
}
return score;
}
use of org.apache.xpath.objects.XNumber in project robovm by robovm.
the class FuncCount method execute.
/**
* Execute the function. The function must return
* a valid object.
* @param xctxt The current execution context.
* @return A valid XObject.
*
* @throws javax.xml.transform.TransformerException
*/
public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
// DTMIterator nl = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
// // We should probably make a function on the iterator for this,
// // as a given implementation could optimize.
// int i = 0;
//
// while (DTM.NULL != nl.nextNode())
// {
// i++;
// }
// nl.detach();
DTMIterator nl = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
int i = nl.getLength();
nl.detach();
return new XNumber((double) i);
}
use of org.apache.xpath.objects.XNumber in project robovm by robovm.
the class FuncSum method execute.
/**
* Execute the function. The function must return
* a valid object.
* @param xctxt The current execution context.
* @return A valid XObject.
*
* @throws javax.xml.transform.TransformerException
*/
public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
DTMIterator nodes = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
double sum = 0.0;
int pos;
while (DTM.NULL != (pos = nodes.nextNode())) {
DTM dtm = nodes.getDTM(pos);
XMLString s = dtm.getStringValue(pos);
if (null != s)
sum += s.toDouble();
}
nodes.detach();
return new XNumber(sum);
}
use of org.apache.xpath.objects.XNumber in project freemarker by apache.
the class XalanXPathSupport method executeQuery.
/* " + ERRMSG_RECOMMEND_JAXEN;*/
public synchronized TemplateModel executeQuery(Object context, String xpathQuery) throws TemplateModelException {
if (!(context instanceof Node)) {
if (context != null) {
if (isNodeList(context)) {
int cnt = ((List) context).size();
if (cnt != 0) {
throw new TemplateModelException("Cannot perform an XPath query against a node set of " + cnt + " nodes. Expecting a single node.");
} else {
throw new TemplateModelException(ERRMSG_EMPTY_NODE_SET);
}
} else {
throw new TemplateModelException("Cannot perform an XPath query against a " + context.getClass().getName() + ". Expecting a single org.w3c.dom.Node.");
}
} else {
throw new TemplateModelException(ERRMSG_EMPTY_NODE_SET);
}
}
Node node = (Node) context;
try {
XPath xpath = new XPath(xpathQuery, null, customPrefixResolver, XPath.SELECT, null);
int ctxtNode = xpathContext.getDTMHandleFromNode(node);
XObject xresult = xpath.execute(xpathContext, ctxtNode, customPrefixResolver);
if (xresult instanceof XNodeSet) {
NodeListModel result = new NodeListModel(node);
result.xpathSupport = this;
NodeIterator nodeIterator = xresult.nodeset();
Node n;
do {
n = nodeIterator.nextNode();
if (n != null) {
result.add(n);
}
} while (n != null);
return result.size() == 1 ? result.get(0) : result;
}
if (xresult instanceof XBoolean) {
return ((XBoolean) xresult).bool() ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
if (xresult instanceof XNull) {
return null;
}
if (xresult instanceof XString) {
return new SimpleScalar(xresult.toString());
}
if (xresult instanceof XNumber) {
return new SimpleNumber(Double.valueOf(((XNumber) xresult).num()));
}
throw new TemplateModelException("Cannot deal with type: " + xresult.getClass().getName());
} catch (TransformerException te) {
throw new TemplateModelException(te);
}
}
Aggregations