Search in sources :

Example 1 with StepPattern

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

use of org.apache.xpath.patterns.StepPattern in project robovm by robovm.

the class FuncCurrent 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 {
    SubContextList subContextList = xctxt.getCurrentNodeList();
    int currentNode = DTM.NULL;
    if (null != subContextList) {
        if (subContextList instanceof PredicatedNodeTest) {
            LocPathIterator iter = ((PredicatedNodeTest) subContextList).getLocPathIterator();
            currentNode = iter.getCurrentContextNode();
        } else if (subContextList instanceof StepPattern) {
            throw new RuntimeException(XSLMessages.createMessage(XSLTErrorResources.ER_PROCESSOR_ERROR, null));
        }
    } else {
        // not predicate => ContextNode == CurrentNode
        currentNode = xctxt.getContextNode();
    }
    return new XNodeSet(currentNode, xctxt.getDTMManager());
}
Also used : PredicatedNodeTest(org.apache.xpath.axes.PredicatedNodeTest) StepPattern(org.apache.xpath.patterns.StepPattern) LocPathIterator(org.apache.xpath.axes.LocPathIterator) SubContextList(org.apache.xpath.axes.SubContextList) XNodeSet(org.apache.xpath.objects.XNodeSet)

Example 3 with StepPattern

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

the class Compiler method stepPattern.

/**
 * Compile a step pattern unit expression, used for both location paths
 * and match patterns.
 *
 * @param opPos The current position in the m_opMap array.
 * @param stepCount The number of steps to expect.
 * @param ancestorPattern The owning StepPattern, which may be null.
 *
 * @return reference to {@link org.apache.xpath.patterns.StepPattern} instance.
 *
 * @throws TransformerException if a error occurs creating the Expression.
 */
protected StepPattern stepPattern(int opPos, int stepCount, StepPattern ancestorPattern) throws TransformerException {
    int startOpPos = opPos;
    int stepType = getOp(opPos);
    if (OpCodes.ENDOP == stepType) {
        return null;
    }
    boolean addMagicSelf = true;
    int endStep = getNextOpPos(opPos);
    // int nextStepType = getOpMap()[endStep];
    StepPattern pattern;
    // boolean isSimple = ((OpCodes.ENDOP == nextStepType) && (stepCount == 0));
    int argLen;
    switch(stepType) {
        case OpCodes.OP_FUNCTION:
            if (DEBUG)
                System.out.println("MATCH_FUNCTION: " + m_currentPattern);
            addMagicSelf = false;
            argLen = getOp(opPos + OpMap.MAPINDEX_LENGTH);
            pattern = new FunctionPattern(compileFunction(opPos), Axis.PARENT, Axis.CHILD);
            break;
        case OpCodes.FROM_ROOT:
            if (DEBUG)
                System.out.println("FROM_ROOT, " + m_currentPattern);
            addMagicSelf = false;
            argLen = getArgLengthOfStep(opPos);
            opPos = getFirstChildPosOfStep(opPos);
            pattern = new StepPattern(DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT, Axis.PARENT, Axis.CHILD);
            break;
        case OpCodes.MATCH_ATTRIBUTE:
            if (DEBUG)
                System.out.println("MATCH_ATTRIBUTE: " + getStepLocalName(startOpPos) + ", " + m_currentPattern);
            argLen = getArgLengthOfStep(opPos);
            opPos = getFirstChildPosOfStep(opPos);
            pattern = new StepPattern(DTMFilter.SHOW_ATTRIBUTE, getStepNS(startOpPos), getStepLocalName(startOpPos), Axis.PARENT, Axis.ATTRIBUTE);
            break;
        case OpCodes.MATCH_ANY_ANCESTOR:
            if (DEBUG)
                System.out.println("MATCH_ANY_ANCESTOR: " + getStepLocalName(startOpPos) + ", " + m_currentPattern);
            argLen = getArgLengthOfStep(opPos);
            opPos = getFirstChildPosOfStep(opPos);
            int what = getWhatToShow(startOpPos);
            // bit-o-hackery, but this code is due for the morgue anyway...
            if (0x00000500 == what)
                addMagicSelf = false;
            pattern = new StepPattern(getWhatToShow(startOpPos), getStepNS(startOpPos), getStepLocalName(startOpPos), Axis.ANCESTOR, Axis.CHILD);
            break;
        case OpCodes.MATCH_IMMEDIATE_ANCESTOR:
            if (DEBUG)
                System.out.println("MATCH_IMMEDIATE_ANCESTOR: " + getStepLocalName(startOpPos) + ", " + m_currentPattern);
            argLen = getArgLengthOfStep(opPos);
            opPos = getFirstChildPosOfStep(opPos);
            pattern = new StepPattern(getWhatToShow(startOpPos), getStepNS(startOpPos), getStepLocalName(startOpPos), Axis.PARENT, Axis.CHILD);
            break;
        default:
            // "unknown match operation!");
            error(XPATHErrorResources.ER_UNKNOWN_MATCH_OPERATION, null);
            return null;
    }
    pattern.setPredicates(getCompiledPredicates(opPos + argLen));
    if (null == ancestorPattern) {
    // This is the magic and invisible "." at the head of every
    // match pattern, and corresponds to the current node in the context
    // list, from where predicates are counted.
    // So, in order to calculate "foo[3]", it has to count from the
    // current node in the context list, so, from that current node,
    // the full pattern is really "self::node()/child::foo[3]".  If you
    // translate this to a select pattern from the node being tested,
    // which is really how we're treating match patterns, it works out to
    // self::foo/parent::node[child::foo[3]]", or close enough.
    /*      if(addMagicSelf && pattern.getPredicateCount() > 0)
      {
        StepPattern selfPattern = new StepPattern(DTMFilter.SHOW_ALL, 
                                                  Axis.PARENT, Axis.CHILD);
        // We need to keep the new nodetest from affecting the score...
        XNumber score = pattern.getStaticScore();
        pattern.setRelativePathPattern(selfPattern);
        pattern.setStaticScore(score);
        selfPattern.setStaticScore(score);
	}*/
    } else {
        // System.out.println("Setting "+ancestorPattern+" as relative to "+pattern);
        pattern.setRelativePathPattern(ancestorPattern);
    }
    StepPattern relativePathPattern = stepPattern(endStep, stepCount + 1, pattern);
    return (null != relativePathPattern) ? relativePathPattern : pattern;
}
Also used : FunctionPattern(org.apache.xpath.patterns.FunctionPattern) StepPattern(org.apache.xpath.patterns.StepPattern)

Example 4 with StepPattern

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

Example 5 with StepPattern

use of org.apache.xpath.patterns.StepPattern in project robovm by robovm.

the class TemplateList method setTemplate.

/**
   * Add a template to the table of named templates and/or the table of templates
   * with match patterns.  This routine should
   * be called in decreasing order of precedence but it checks nonetheless.
   *
   * @param template
   */
public void setTemplate(ElemTemplate template) {
    XPath matchXPath = template.getMatch();
    if (null == template.getName() && null == matchXPath) {
        template.error(XSLTErrorResources.ER_NEED_NAME_OR_MATCH_ATTRIB, new Object[] { "xsl:template" });
    }
    if (null != template.getName()) {
        ElemTemplate existingTemplate = (ElemTemplate) m_namedTemplates.get(template.getName());
        if (null == existingTemplate) {
            m_namedTemplates.put(template.getName(), template);
        } else {
            int existingPrecedence = existingTemplate.getStylesheetComposed().getImportCountComposed();
            int newPrecedence = template.getStylesheetComposed().getImportCountComposed();
            if (newPrecedence > existingPrecedence) {
                // This should never happen
                m_namedTemplates.put(template.getName(), template);
            } else if (newPrecedence == existingPrecedence)
                template.error(XSLTErrorResources.ER_DUPLICATE_NAMED_TEMPLATE, new Object[] { template.getName() });
        }
    }
    if (null != matchXPath) {
        Expression matchExpr = matchXPath.getExpression();
        if (matchExpr instanceof StepPattern) {
            insertPatternInTable((StepPattern) matchExpr, template);
        } else if (matchExpr instanceof UnionPattern) {
            UnionPattern upat = (UnionPattern) matchExpr;
            StepPattern[] pats = upat.getPatterns();
            int n = pats.length;
            for (int i = 0; i < n; i++) {
                insertPatternInTable(pats[i], template);
            }
        } else {
        // TODO: assert error
        }
    }
}
Also used : XPath(org.apache.xpath.XPath) Expression(org.apache.xpath.Expression) StepPattern(org.apache.xpath.patterns.StepPattern) UnionPattern(org.apache.xpath.patterns.UnionPattern)

Aggregations

StepPattern (org.apache.xpath.patterns.StepPattern)12 Expression (org.apache.xpath.Expression)4 ContextMatchStepPattern (org.apache.xpath.patterns.ContextMatchStepPattern)4 FunctionPattern (org.apache.xpath.patterns.FunctionPattern)4 UnionPattern (org.apache.xpath.patterns.UnionPattern)4 XPath (org.apache.xpath.XPath)2 LocPathIterator (org.apache.xpath.axes.LocPathIterator)2 PredicatedNodeTest (org.apache.xpath.axes.PredicatedNodeTest)2 SubContextList (org.apache.xpath.axes.SubContextList)2 XNodeSet (org.apache.xpath.objects.XNodeSet)2 XNumber (org.apache.xpath.objects.XNumber)2