You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mm...@locus.apache.org on 2000/09/12 16:12:29 UTC

cvs commit: xml-xalan/src/org/apache/xalan/xpath SimpleNodeLocator.java

mmidy       00/09/12 07:12:29

  Modified:    src/org/apache/xalan/xpath SimpleNodeLocator.java
  Log:
  Fix problem with a match pattern like [predicate]//node()
  
  Revision  Changes    Path
  1.27      +87 -55    xml-xalan/src/org/apache/xalan/xpath/SimpleNodeLocator.java
  
  Index: SimpleNodeLocator.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/src/org/apache/xalan/xpath/SimpleNodeLocator.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- SimpleNodeLocator.java	2000/07/21 15:00:16	1.26
  +++ SimpleNodeLocator.java	2000/09/12 14:12:28	1.27
  @@ -1502,7 +1502,8 @@
      */
     protected Node stepPattern(XPath xpath, XPathSupport execContext, Node context, int opPos, double scoreHolder[]) 
       throws org.xml.sax.SAXException
  -  {    
  +  {
  +    boolean predicateDone = false;
       int startOpPos = opPos;
       int stepType = xpath.m_opMap[opPos];
       
  @@ -1578,7 +1579,15 @@
           {
             score = nodeTest(xpath, execContext, context, opPos, argLen, stepType);
             if(XPath.MATCH_SCORE_NONE != score)
  -            break;
  +          {
  +            if (XPath.OP_PREDICATE == xpath.m_opMap[opPos+argLen])
  +            {  
  +              score = doPredicate(xpath, execContext, context, opPos, argLen, startOpPos);
  +              predicateDone = true;
  +            }
  +            if(XPath.MATCH_SCORE_NONE != score)
  +              break;
  +          }  
             // context = execContext.getParentOfNode(context);
             context = context.getParentNode();
           }
  @@ -1607,70 +1616,93 @@
         xpath.error(context, XPATHErrorResources.ER_UNKNOWN_MATCH_OPERATION); //"unknown match operation!");
         break;
       }
  +    
  +    //opPos += argLen;
  +    nextStepType = xpath.m_opMap[opPos+argLen];
  +    
  +    if(((score != XPath.MATCH_SCORE_NONE))
  +       && (!predicateDone)
  +       && (XPath.OP_PREDICATE == nextStepType))    
  +      score = doPredicate(xpath, execContext, context, opPos, argLen, startOpPos);
  +    
  +    // If we haven't found a score yet, or the test was 
  +    // negative, assign the score.
  +    if((scoreHolder[0] == XPath.MATCH_SCORE_NONE) || 
  +       (score == XPath.MATCH_SCORE_NONE))
  +      scoreHolder[0] = score;
  +    
  +    return (score == XPath.MATCH_SCORE_NONE) ? null : context;
  +  }
  +  
  +  /**
  +   * Test a node to see if it matches the predicate test.
  +   * @param xpath The xpath that is executing.
  +   * @param context The current source tree context node.
  +   * @param opPos The current position in the xpath.m_opMap array.
  +   * @param argLen The length of the argument.
  +   * @param startOpPos The original position in the xpath.m_opMap array.
  +   * @returns score in an XNumber, one of MATCH_SCORE_NODETEST, 
  +   * MATCH_SCORE_NONE, MATCH_SCORE_OTHER, MATCH_SCORE_QNAME.
  +   */
  +  public double doPredicate(XPath xpath, XPathSupport execContext, Node context, int opPos, int argLen, int startOpPos)
  +    throws org.xml.sax.SAXException
  +  {
  +    double score;
       opPos += argLen;
  -    nextStepType = xpath.m_opMap[opPos];
  +    int nextStepType;    
       
  -    if(((score != XPath.MATCH_SCORE_NONE)) && (XPath.OP_PREDICATE == nextStepType))
  +    score = XPath.MATCH_SCORE_OTHER;
  +    // Execute the xpath.predicates, but if we have an index, then we have 
  +    // to start over and do a search from the parent.  It would be nice 
  +    // if I could sense this condition earlier...
  +    try
       {
  -      score = XPath.MATCH_SCORE_OTHER;
  -      // Execute the xpath.predicates, but if we have an index, then we have 
  -      // to start over and do a search from the parent.  It would be nice 
  -      // if I could sense this condition earlier...
  -      try
  -      {
  -        // BUG: m_throwFoundIndex is not threadsafe
  -        execContext.setThrowFoundIndex(true);
  -        int startPredicates = opPos;
  -        opPos = startPredicates;
  -        nextStepType = xpath.m_opMap[opPos];
  -        while(XPath.OP_PREDICATE == nextStepType)
  +      // BUG: m_throwFoundIndex is not threadsafe
  +      execContext.setThrowFoundIndex(true);
  +      int startPredicates = opPos;
  +      opPos = startPredicates;
  +      nextStepType = xpath.m_opMap[opPos];
  +      while(XPath.OP_PREDICATE == nextStepType)
  +      {
  +        XObject pred = xpath.predicate(execContext, context, opPos);
  +        if(XObject.CLASS_NUMBER == pred.getType())
           {
  -          XObject pred = xpath.predicate(execContext, context, opPos);
  -          if(XObject.CLASS_NUMBER == pred.getType())
  -          {
  -            throw new FoundIndex();
  -          }
  -          else if(!pred.bool())
  -          {
  -            score = XPath.MATCH_SCORE_NONE;
  -            break; // from while(XPath.OP_PREDICATE == nextStepType)
  -          }
  -          opPos = xpath.getNextOpPos(opPos);
  -          nextStepType = xpath.m_opMap[opPos];
  +          throw new FoundIndex();
  +        }
  +        else if(!pred.bool())
  +        {
  +          score = XPath.MATCH_SCORE_NONE;
  +          break; // from while(XPath.OP_PREDICATE == nextStepType)
           }
  -        execContext.setThrowFoundIndex(false);
  +        opPos = xpath.getNextOpPos(opPos);
  +        nextStepType = xpath.m_opMap[opPos];
         }
  -      catch(FoundIndex fi)
  +      execContext.setThrowFoundIndex(false);
  +    }
  +    catch(FoundIndex fi)
  +    {
  +      // We have an index somewhere in our pattern.  So, we have 
  +      // to do a full search for our step, using the parent as 
  +      // context, then see if the current context is found in the 
  +      // node set.  Seems crazy, but, so far, it seems like the 
  +      // easiest way.
  +      execContext.setThrowFoundIndex(false);
  +      Node parentContext = execContext.getParentOfNode(context);
  +      MutableNodeList mnl = step(xpath, execContext, parentContext, startOpPos, null, null, false, false);
  +      int nNodes = mnl.getLength();
  +      score = XPath.MATCH_SCORE_NONE;
  +      for(int i = 0; i < nNodes; i++)
         {
  -        // We have an index somewhere in our pattern.  So, we have 
  -        // to do a full search for our step, using the parent as 
  -        // context, then see if the current context is found in the 
  -        // node set.  Seems crazy, but, so far, it seems like the 
  -        // easiest way.
  -        execContext.setThrowFoundIndex(false);
  -        Node parentContext = execContext.getParentOfNode(context);
  -        MutableNodeList mnl = step(xpath, execContext, parentContext, startOpPos, null, null, false, false);
  -        int nNodes = mnl.getLength();
  -        score = XPath.MATCH_SCORE_NONE;
  -        for(int i = 0; i < nNodes; i++)
  +        Node child = mnl.item(i);
  +        if((null != child) && child.equals( context ))
           {
  -          Node child = mnl.item(i);
  -          if((null != child) && child.equals( context ))
  -          {
  -            score = XPath.MATCH_SCORE_OTHER;
  -            break;
  -          }
  +          score = XPath.MATCH_SCORE_OTHER;
  +          break;
           }
         }
       }
  -    // If we haven't found a score yet, or the test was 
  -    // negative, assign the score.
  -    if((scoreHolder[0] == XPath.MATCH_SCORE_NONE) || 
  -       (score == XPath.MATCH_SCORE_NONE))
  -      scoreHolder[0] = score;
  -    
  -    return (score == XPath.MATCH_SCORE_NONE) ? null : context;
  -  }
  +    return score;    
  +  }  
   
     
     /**