Search in sources :

Example 1 with XNumber

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;
}
Also used : XNumber(org.apache.xpath.objects.XNumber) ContextMatchStepPattern(org.apache.xpath.patterns.ContextMatchStepPattern) StepPattern(org.apache.xpath.patterns.StepPattern) ContextMatchStepPattern(org.apache.xpath.patterns.ContextMatchStepPattern)

Example 2 with XNumber

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;
}
Also used : XNumber(org.apache.xpath.objects.XNumber) DTMIterator(org.apache.xml.dtm.DTMIterator)

Example 3 with XNumber

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);
}
Also used : XNumber(org.apache.xpath.objects.XNumber) DTMIterator(org.apache.xml.dtm.DTMIterator)

Example 4 with XNumber

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);
}
Also used : XNumber(org.apache.xpath.objects.XNumber) DTM(org.apache.xml.dtm.DTM) XMLString(org.apache.xml.utils.XMLString) DTMIterator(org.apache.xml.dtm.DTMIterator)

Example 5 with XNumber

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);
    }
}
Also used : XPath(org.apache.xpath.XPath) NodeIterator(org.w3c.dom.traversal.NodeIterator) TemplateModelException(freemarker.template.TemplateModelException) XNull(org.apache.xpath.objects.XNull) XNumber(org.apache.xpath.objects.XNumber) Node(org.w3c.dom.Node) XBoolean(org.apache.xpath.objects.XBoolean) SimpleScalar(freemarker.template.SimpleScalar) XNodeSet(org.apache.xpath.objects.XNodeSet) SimpleNumber(freemarker.template.SimpleNumber) XString(org.apache.xpath.objects.XString) List(java.util.List) XObject(org.apache.xpath.objects.XObject) TransformerException(javax.xml.transform.TransformerException)

Aggregations

XNumber (org.apache.xpath.objects.XNumber)17 DTMIterator (org.apache.xml.dtm.DTMIterator)10 XObject (org.apache.xpath.objects.XObject)3 DTM (org.apache.xml.dtm.DTM)2 XMLString (org.apache.xml.utils.XMLString)2 ContextMatchStepPattern (org.apache.xpath.patterns.ContextMatchStepPattern)2 StepPattern (org.apache.xpath.patterns.StepPattern)2 SimpleNumber (freemarker.template.SimpleNumber)1 SimpleScalar (freemarker.template.SimpleScalar)1 TemplateModelException (freemarker.template.TemplateModelException)1 List (java.util.List)1 TransformerException (javax.xml.transform.TransformerException)1 XPath (org.apache.xpath.XPath)1 XBoolean (org.apache.xpath.objects.XBoolean)1 XNodeSet (org.apache.xpath.objects.XNodeSet)1 XNull (org.apache.xpath.objects.XNull)1 XString (org.apache.xpath.objects.XString)1 Node (org.w3c.dom.Node)1 NodeIterator (org.w3c.dom.traversal.NodeIterator)1