Search in sources :

Example 1 with ContextMatchStepPattern

use of org.apache.xpath.patterns.ContextMatchStepPattern 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 ContextMatchStepPattern

use of org.apache.xpath.patterns.ContextMatchStepPattern in project j2objc by google.

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)

Aggregations

XNumber (org.apache.xpath.objects.XNumber)2 ContextMatchStepPattern (org.apache.xpath.patterns.ContextMatchStepPattern)2 StepPattern (org.apache.xpath.patterns.StepPattern)2