dbertoni    01/10/24 08:44:51

  Modified:    c/src/XPath XPath.cpp XPath.hpp
  Log:
  XPath/SimpleNodeLocator integration.
  
  Revision  Changes    Path
  1.63      +2317 -4   xml-xalan/c/src/XPath/XPath.cpp
  
  Index: XPath.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XPath.cpp,v
  retrieving revision 1.62
  retrieving revision 1.63
  diff -u -r1.62 -r1.63
  --- XPath.cpp 2001/09/14 20:06:26     1.62
  +++ XPath.cpp 2001/10/24 15:44:51     1.63
  @@ -71,15 +71,22 @@
   
   
   
  +#include <XalanDOM/XalanNamedNodeMap.hpp>
  +
  +
  +
   #include <PlatformSupport/DoubleSupport.hpp>
   #include <PlatformSupport/PrefixResolver.hpp>
   
   
   
  +#include <DOMSupport/DOMServices.hpp>
  +
  +
  +
   #include "FoundIndex.hpp"
   #include "MutableNodeRefList.hpp"
   #include "XalanQNameByReference.hpp"
  -#include "SimpleNodeLocator.hpp"
   #include "XLocator.hpp"
   #include "XPathException.hpp"
   #include "XObject.hpp"
  @@ -88,6 +95,10 @@
   
   
   
  +const XalanDOMString XPath::s_emptyString;
  +
  +
  +
   XPath::XPath(const Locator*  theLocator) :
        m_expression(),
        m_locator(theLocator),
  @@ -302,7 +313,7 @@
        {
                const int       nextOpPos = 
m_expression.getNextOpCodePosition(opPos);
   
  -             score = SimpleNodeLocator::locationPathPattern(*this, 
executionContext, *context, opPos);
  +             score = locationPathPattern(executionContext, *context, opPos);
   
                if(score == eMatchScoreNone)
                {
  @@ -954,7 +965,7 @@
   {    
        assert(context != 0);
   
  -     return SimpleNodeLocator::locationPath(*this, executionContext, 
*context, opPos);
  +     return locationPath(executionContext, *context, opPos);
   }
   
   
  @@ -968,7 +979,7 @@
        assert(context != 0);
   
        const eMatchScore       result =
  -             SimpleNodeLocator::locationPathPattern(*this, executionContext, 
*context, opPos);
  +             locationPathPattern(executionContext, *context, opPos);
   
        return 
executionContext.getXObjectFactory().createNumber(getMatchScoreValue(result));
   }
  @@ -1112,6 +1123,2308 @@
   
                return function(context, funcID, args, executionContext);
        }
  +}
  +
  +
  +
  +const XObjectPtr
  +XPath::locationPath(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode&                              context, 
  +                     int                                     opPos) const
  +{
  +     typedef XPathExecutionContext::BorrowReturnMutableNodeRefList   
BorrowReturnMutableNodeRefList;
  +
  +     BorrowReturnMutableNodeRefList  mnl(executionContext);
  +
  +     step(executionContext, &context, opPos + 2, *mnl.get());
  +
  +     return executionContext.getXObjectFactory().createNodeSet(mnl);
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::locationPathPattern(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode&                              context, 
  +                     int                                     opPos) const
  +{
  +     eMatchScore     score = eMatchScoreNone;
  +
  +     stepPattern(executionContext, &context, opPos + 2, score);
  +
  +     return score;
  +}
  +
  +
  +
  +void
  +XPath::step(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     MutableNodeRefList&     queryResults) const
  +{
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // int endStep = xpath.getNextOpPos(opPos);
  +     const int       stepType =
  +             currentExpression.getOpCodeMapValue(opPos);
  +
  +     int             argLen = 0;
  +
  +     typedef XPathExecutionContext::BorrowReturnMutableNodeRefList   
BorrowReturnMutableNodeRefList;
  +
  +     BorrowReturnMutableNodeRefList  subQueryResults(executionContext);
  +
  +     bool    shouldReorder = false;
  +     bool    continueStepRecursion = true;
  +
  +     switch(stepType)
  +     {
  +     case XPathExpression::eOP_VARIABLE:
  +     case XPathExpression::eOP_EXTFUNCTION:
  +     case XPathExpression::eOP_FUNCTION:
  +     case XPathExpression::eOP_GROUP:
  +             argLen = findNodeSet(executionContext, context, opPos, 
stepType, *subQueryResults);
  +             break;
  +
  +     case XPathExpression::eFROM_ROOT:
  +             argLen = findRoot(executionContext, context, opPos, stepType, 
*subQueryResults);
  +             break;
  +
  +     case XPathExpression::eFROM_PARENT:
  +             argLen = findParent(executionContext, context, opPos, stepType, 
*subQueryResults);
  +             break;
  +
  +     case XPathExpression::eFROM_SELF:
  +             argLen = findSelf(executionContext, context, opPos, stepType, 
*subQueryResults);
  +             break;
  +
  +     case XPathExpression::eFROM_ANCESTORS:
  +             argLen = findAncestors(executionContext, context, opPos, 
stepType, *subQueryResults);
  +             shouldReorder = true;
  +             break;
  +
  +     case XPathExpression::eFROM_ANCESTORS_OR_SELF:
  +             argLen = findAncestorsOrSelf(executionContext, context, opPos, 
stepType, *subQueryResults);
  +             shouldReorder = true;
  +             break;
  +
  +     case XPathExpression::eMATCH_ATTRIBUTE:
  +             continueStepRecursion = false;
  +             // fall-through on purpose.
  +
  +     case XPathExpression::eFROM_ATTRIBUTES:
  +             argLen = findAttributes(executionContext, context, opPos, 
stepType, *subQueryResults);
  +             break;
  +
  +     case XPathExpression::eMATCH_ANY_ANCESTOR:
  +     case XPathExpression::eMATCH_IMMEDIATE_ANCESTOR:
  +     case XPathExpression::eMATCH_ANY_ANCESTOR_WITH_PREDICATE:
  +             continueStepRecursion = false;
  +             // fall-through on purpose.
  +
  +     case XPathExpression::eFROM_CHILDREN:
  +             argLen = findChildren(executionContext, context, opPos, 
stepType, *subQueryResults);
  +             break;
  +
  +     case XPathExpression::eFROM_DESCENDANTS:
  +     case XPathExpression::eFROM_DESCENDANTS_OR_SELF:
  +             argLen = findDescendants(executionContext, context, opPos, 
stepType, *subQueryResults);
  +             break;
  +
  +     case XPathExpression::eFROM_FOLLOWING:
  +             argLen = findFollowing(executionContext, context, opPos, 
stepType, *subQueryResults);
  +             break;
  +
  +     case XPathExpression::eFROM_FOLLOWING_SIBLINGS:
  +             argLen = findFollowingSiblings(executionContext, context, 
opPos, stepType, *subQueryResults);
  +             break;
  +
  +     case XPathExpression::eFROM_PRECEDING:
  +             argLen = findPreceeding(executionContext, context, opPos, 
stepType, *subQueryResults);
  +             shouldReorder = true;
  +             break;
  +
  +     case XPathExpression::eFROM_PRECEDING_SIBLINGS:
  +             argLen = findPreceedingSiblings(executionContext, context, 
opPos, stepType, *subQueryResults);
  +             shouldReorder = true;
  +             break;
  +
  +     case XPathExpression::eFROM_NAMESPACE:
  +             argLen = findNamespace(executionContext, context, opPos,  
stepType, *subQueryResults);
  +             break;
  +
  +     default:
  +             argLen = findNodesOnUnknownAxis(executionContext, context, 
opPos, stepType, *subQueryResults);
  +             break;
  +     }
  +
  +     // Push and pop the PrefixResolver...
  +     XPathExecutionContext::ContextNodeListSetAndRestore             
theSetAndRestore(
  +                                                                     
executionContext,
  +                                                                     
*subQueryResults);
  +
  +     opPos += argLen;
  +
  +     int             nextStepType = 
currentExpression.getOpCodeMapValue(opPos);
  +
  +     if(XPathExpression::eOP_PREDICATE == nextStepType)
  +     {
  +             predicates(executionContext,
  +                                context,
  +                                opPos, 
  +                                *subQueryResults,
  +                                opPos);
  +
  +             nextStepType = currentExpression.getOpCodeMapValue(opPos);
  +     }
  +
  +     if(XPathExpression::eENDOP != nextStepType && continueStepRecursion == 
true)
  +     {
  +             const NodeRefListBase::size_type        nContexts = 
subQueryResults->getLength();
  +
  +             for(NodeRefListBase::size_type i = 0; i < nContexts; i++)
  +             {
  +                     XalanNode* const        node = subQueryResults->item(i);
  +
  +                     if(0 != node)
  +                     {
  +                             BorrowReturnMutableNodeRefList  
mnl(executionContext);
  +
  +                             step(executionContext, node, opPos, *mnl);
  +
  +                             if (mnl->getLength() > 0)
  +                             {
  +                                     if(queryResults.getLength() == 0)
  +                                     {
  +                                             queryResults = *mnl;
  +                                     }
  +                                     else
  +                                     {
  +                                             
queryResults.addNodesInDocOrder(*mnl, executionContext);
  +                                     }
  +                             }
  +                     }
  +             }
  +     }
  +     else
  +     {
  +             if (shouldReorder == true)
  +             {
  +                     queryResults.addNodesInDocOrder(*subQueryResults, 
executionContext);
  +             }
  +             else
  +             {
  +                     queryResults = *subQueryResults;
  +             }
  +     }
  +}
  +
  +
  +
  +XalanNode*
  +XPath::stepPattern(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     eMatchScore&                    scoreHolder) const
  +{
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     const int       endStep = 
currentExpression.getNextOpCodePosition(opPos);
  +     int             nextStepType = 
currentExpression.getOpCodeMapValue(endStep);
  +
  +     if(XPathExpression::eENDOP != nextStepType)
  +     {
  +             // Continue step via recursion...
  +             context = stepPattern(
  +                                             executionContext,
  +                                             context,
  +                                             endStep,
  +                                             scoreHolder);
  +
  +             if(0 == context)
  +             {
  +                     scoreHolder = eMatchScoreNone;
  +
  +             }
  +
  +             if (scoreHolder == eMatchScoreNone)
  +             {
  +                     // !!!!!!!!!!!!! Big ugly return here 
!!!!!!!!!!!!!!!!!!!
  +                     return 0;
  +             }
  +
  +             scoreHolder = eMatchScoreOther;
  +
  +             if (nextStepType != 
XPathExpression::eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL)
  +             {
  +                     context = DOMServices::getParentOfNode(*context);
  +             }
  +
  +             if(0 == context)
  +             {
  +                     // !!!!!!!!!!!!! Big ugly return here 
!!!!!!!!!!!!!!!!!!!
  +                     return 0;
  +             }
  +     }
  +
  +     assert(context != 0);
  +
  +     int                                     argLen = 0;
  +
  +     eMatchScore     score = eMatchScoreNone;
  +
  +     const int       startOpPos = opPos;
  +     const int       stepType = currentExpression.getOpCodeMapValue(opPos);
  +
  +     switch(stepType)
  +     {
  +     case XPathExpression::eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL:
  +             score = scoreHolder;
  +             break;
  +
  +     case XPathExpression::eOP_FUNCTION:
  +             {
  +                     argLen = 
currentExpression.getOpCodeLengthFromOpMap(opPos);
  +
  +                     const XObjectPtr                
obj(executeMore(context, opPos, executionContext));
  +                     assert(obj.get() != 0);
  +
  +                     const NodeRefListBase&                          nl = 
obj->nodeset();
  +
  +                     const NodeRefListBase::size_type        len = 
nl.getLength();
  +
  +                     if (nextStepType == 
XPathExpression::eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL)
  +                     {
  +                             bool    fFound = false;
  +
  +                             while(context != 0 && fFound == false)
  +                             {
  +                                     for(NodeRefListBase::size_type i = 0; i 
< len; i++)
  +                                     {
  +                                             XalanNode* const        n = 
nl.item(i);
  +
  +                                             if(n == context)
  +                                             {
  +                                                     score = 
eMatchScoreOther;
  +
  +                                                     context = n;
  +
  +                                                     fFound = true;
  +
  +                                                     break;
  +                                             }
  +                                     }
  +
  +                                     context = 
DOMServices::getParentOfNode(*context);
  +                             }
  +                     }
  +                     else
  +                     {
  +                             for(NodeRefListBase::size_type i = 0; i < len; 
i++)
  +                             {
  +                                     XalanNode* const        n = nl.item(i);
  +
  +                                     if(n == context)
  +                                     {
  +                                             score = eMatchScoreOther;
  +
  +                                             context = n;
  +
  +                                             break;
  +                                     }
  +                             }
  +                     }
  +             }
  +             break;
  +
  +     case XPathExpression::eFROM_ROOT:
  +             {
  +                     // $$ ToDO: Can we reduce this to some call on the
  +                     // XPathExpression interface?
  +                     argLen =
  +                             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +                     opPos += 3;
  +
  +                     const XalanNode::NodeType       nodeType = 
context->getNodeType();
  +
  +                     if (nodeType == XalanNode::DOCUMENT_NODE ||
  +                             nodeType == XalanNode::DOCUMENT_FRAGMENT_NODE)
  +                     {
  +                             score = eMatchScoreOther;
  +                     }
  +                     else
  +                     {
  +                             const int   prevPos = 
currentExpression.getNextOpCodePosition(startOpPos);              
  +                             const int       prevStepType = 
currentExpression.getOpCodeMapValue(prevPos);
  +
  +                             if (eMatchScoreNone == score  && 
  +                                 (prevStepType == 
XPathExpression::eMATCH_ANY_ANCESTOR ||
  +                                      prevStepType == 
XPathExpression::eMATCH_ANY_ANCESTOR_WITH_PREDICATE))
  +                             {
  +                                     const NodeTester        theTester(
  +                                                                     *this,
  +                                                                     
executionContext,
  +                                                                     opPos,
  +                                                                     argLen,
  +                                                                     
stepType);
  +
  +                                     while(0 != context)
  +                                     {
  +                                             score =
  +                                                     theTester(*context, 
context->getNodeType());
  +                                                     assert(score == 
nodeTest(executionContext, context, context->getNodeType(), opPos, argLen, 
stepType));
  +
  +                                             if(eMatchScoreNone != score)
  +                                                     break;
  +
  +                                             context = 
DOMServices::getParentOfNode(*context);
  +                                     }
  +                             }
  +                     }
  +             }
  +             break;
  +
  +     case XPathExpression::eMATCH_ATTRIBUTE:
  +             {
  +                     // $$ ToDO: Can we reduce this to some call on the
  +                     // XPathExpression interface?
  +                     argLen =
  +                             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +                     opPos += 3;
  +
  +                     score = NodeTester(
  +                                                     *this,
  +                                                     executionContext,
  +                                                     opPos,
  +                                                     argLen,
  +                                                     
XPathExpression::eFROM_ATTRIBUTES)(*context, context->getNodeType());
  +
  +                     assert(score == nodeTest(
  +                                                      executionContext,
  +                                                      context,
  +                                                      context->getNodeType(),
  +                                                      opPos,
  +                                                      argLen,
  +                                                      
XPathExpression::eFROM_ATTRIBUTES));
  +             }
  +             break;
  +
  +     case XPathExpression::eMATCH_ANY_ANCESTOR:
  +     case XPathExpression::eMATCH_ANY_ANCESTOR_WITH_PREDICATE:
  +             {
  +                     // $$ ToDO: Can we reduce this to some call on the
  +                     // XPathExpression interface?
  +                     argLen =
  +                                     
currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +                     XalanNode::NodeType             nodeType = 
context->getNodeType();
  +
  +                     if(nodeType != XalanNode::ATTRIBUTE_NODE)
  +                     {
  +                             opPos += 3;
  +
  +                             const NodeTester        theTester(
  +                                                                     *this,
  +                                                                     
executionContext,
  +                                                                     opPos,
  +                                                                     argLen,
  +                                                                     
stepType);
  +
  +                             for(;;)
  +                             {
  +                                     score = theTester(*context, nodeType);
  +                                     assert(score == 
nodeTest(executionContext, context, nodeType, opPos, argLen, stepType));
  +
  +                                     if(eMatchScoreNone != score)
  +                                             break;
  +
  +                                     context = 
DOMServices::getParentOfNode(*context);
  +
  +                                     if (context == 0)
  +                                             break;
  +
  +                                     nodeType = context->getNodeType();
  +                             }
  +                     }
  +             }
  +             break;
  +
  +     case XPathExpression::eMATCH_IMMEDIATE_ANCESTOR:
  +             {
  +                     // $$ ToDO: Can we reduce this to some call on the
  +                     // XPathExpression interface?
  +                     argLen =
  +                             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +                     const XalanNode::NodeType       nodeType = 
context->getNodeType();
  +
  +                     if(nodeType != XalanNode::ATTRIBUTE_NODE)
  +                     {
  +                             opPos += 3;
  +
  +                             score = NodeTester(
  +                                                             *this,
  +                                                             
executionContext,
  +                                                             opPos,
  +                                                             argLen,
  +                                                             
XPathExpression::eMATCH_IMMEDIATE_ANCESTOR)(*context, nodeType);
  +
  +                             assert(score == nodeTest(
  +                                                              
executionContext,
  +                                                              context,
  +                                                              nodeType,
  +                                                              opPos,
  +                                                              argLen,
  +                                                              
XPathExpression::eMATCH_IMMEDIATE_ANCESTOR));
  +                     }
  +             }
  +             break;
  +
  +     default:
  +             executionContext.error(TranscodeFromLocalCodePage("unknown 
match operation!"), context, getLocator());
  +             break;
  +     }
  +
  +     opPos += argLen;
  +
  +     nextStepType = currentExpression.getOpCodeMapValue(opPos);
  +
  +     if(score != eMatchScoreNone && XPathExpression::eOP_PREDICATE == 
nextStepType)
  +     {
  +             score = eMatchScoreOther;
  +
  +             // 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
  +             {
  +                     executionContext.setThrowFoundIndex(true);
  +
  +                     while(XPathExpression::eOP_PREDICATE == nextStepType)
  +                     {
  +                             const XObjectPtr                
pred(predicate(context, opPos, executionContext));
  +                             assert(pred.get() != 0);
  +
  +                             if(XObject::eTypeNumber == pred->getType())
  +                             {
  +                                     score = 
handleFoundIndex(executionContext, context, startOpPos);
  +                             }
  +                             else if(pred->boolean() == false)
  +                             {
  +                                     score = eMatchScoreNone;
  +
  +                                     break;
  +                             }
  +
  +                             opPos = 
currentExpression.getNextOpCodePosition(opPos);
  +                             nextStepType = 
currentExpression.getOpCodeMapValue(opPos);
  +                     }
  +
  +                     executionContext.setThrowFoundIndex(false);
  +             }
  +             catch(const FoundIndex&)
  +             {
  +                     score = handleFoundIndex(executionContext, context, 
startOpPos);
  +             }
  +     }
  +
  +     if (scoreHolder == eMatchScoreNone || 
  +        score == eMatchScoreNone)
  +     {
  +             scoreHolder = score;
  +     }
  +
  +     return score == eMatchScoreNone ? 0 : context;
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::handleFoundIndex(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              localContext, 
  +                     int                                     startOpPos) 
const
  +{
  +     // We have an index somewhere in our pattern.  So, we have 
  +     // to do a full search for our step, using the parent as 
  +     // localContext, then see if the current localContext is found in the 
  +     // node set.  Seems crazy, but, so far, it seems like the 
  +     // easiest way.
  +     executionContext.setThrowFoundIndex(false);
  +
  +     XalanNode* const        parentContext =
  +                             DOMServices::getParentOfNode(*localContext);
  +
  +     if (parentContext == 0)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             typedef XPathExecutionContext::BorrowReturnMutableNodeRefList   
BorrowReturnMutableNodeRefList;
  +
  +             BorrowReturnMutableNodeRefList  mnl(executionContext);
  +
  +             step(executionContext, parentContext, startOpPos, *mnl);
  +
  +             if (mnl->indexOf(localContext) == MutableNodeRefList::npos)
  +             {
  +                     return eMatchScoreNone;
  +             }
  +             else
  +             {
  +                     return eMatchScoreOther;
  +             }
  +     }
  +}
  +
  +
  +
  +int
  +XPath::findNodeSet(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     /* stepType */,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     const XObjectPtr                obj(executeMore(context, opPos, 
executionContext));
  +
  +     const NodeRefListBase&  nl = obj->nodeset();
  +
  +     subQueryResults.addNodes(nl);
  +
  +     return currentExpression.getOpCodeLengthFromOpMap(opPos);
  +}
  +
  +
  +
  +int
  +XPath::findRoot(
  +                     XPathExecutionContext&  /* executionContext */,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     /* stepType */,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     XalanNode* const        docContext = XalanNode::DOCUMENT_NODE == 
context->getNodeType() ?
  +                                                                     context 
:
  +                                                                     
context->getOwnerDocument();
  +     assert(docContext != 0);
  +
  +     subQueryResults.addNode(docContext);
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findParent(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +                     currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     XalanNode* const        theParent = 
DOMServices::getParentOfNode(*context);
  +
  +     if(0 != theParent)
  +     {
  +             if(argLen > 0)
  +             {
  +                     opPos += 3;
  +
  +                     const NodeTester        theTester(
  +                                                     *this,
  +                                                     executionContext,
  +                                                     opPos,
  +                                                     argLen,
  +                                                     stepType);
  +
  +                     const eMatchScore       score = theTester(*theParent, 
theParent->getNodeType());
  +                     assert(score == nodeTest(executionContext, theParent, 
theParent->getNodeType(), opPos, argLen, stepType));
  +
  +                     if(eMatchScoreNone != score)
  +                     {
  +                             subQueryResults.addNode(theParent);
  +                     }
  +             }
  +             else
  +             {
  +                     subQueryResults.addNode(theParent);
  +             }
  +     }
  +
  +     subQueryResults.setDocumentOrder();
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findSelf(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     if(argLen == 0)
  +     {
  +             subQueryResults.addNode(context);
  +     }
  +     else
  +     {
  +             opPos += 3;
  +
  +             const NodeTester        theTester(
  +                                             *this,
  +                                             executionContext,
  +                                             opPos,
  +                                             argLen,
  +                                             stepType);
  +
  +             const eMatchScore       score =
  +                     theTester(*context, context->getNodeType());
  +                     assert(score == nodeTest(executionContext, context, 
context->getNodeType(), opPos, argLen, stepType));
  +
  +             if(eMatchScoreNone != score)
  +             {
  +                     subQueryResults.addNode(context);
  +             }
  +     }
  +
  +     subQueryResults.setDocumentOrder();
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findAncestors(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     context = DOMServices::getParentOfNode(*context);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +                     currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     if (context != 0)
  +     {
  +             opPos += 3;
  +
  +             const NodeTester        theTester(
  +                                             *this,
  +                                             executionContext,
  +                                             opPos,
  +                                             argLen,
  +                                             stepType);
  +
  +             do
  +             {
  +                     const eMatchScore       score =
  +                             theTester(*context, context->getNodeType());
  +                             assert(score == nodeTest(executionContext, 
context, context->getNodeType(), opPos, argLen, stepType));
  +
  +                     if(eMatchScoreNone != score)
  +                     {
  +                             subQueryResults.addNode(context);
  +                     }
  +
  +                     context = DOMServices::getParentOfNode(*context);
  +             } while(0 != context);
  +
  +             subQueryResults.setReverseDocumentOrder();
  +     }
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findAncestorsOrSelf(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     opPos += 3;
  +
  +     const NodeTester        theTester(
  +                                     *this,
  +                                     executionContext,
  +                                     opPos,
  +                                     argLen,
  +                                     stepType);
  +
  +     do
  +     {
  +             const eMatchScore       score =
  +                             theTester(*context, context->getNodeType());
  +                             assert(score == nodeTest(executionContext, 
context, context->getNodeType(), opPos, argLen, stepType));
  +
  +             if(eMatchScoreNone != score)
  +             {
  +                     subQueryResults.addNode(context);
  +             }
  +
  +             context = DOMServices::getParentOfNode(*context);
  +     } while(0 != context);
  +
  +     subQueryResults.setReverseDocumentOrder();
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findAttributes(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +                             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     if(context->getNodeType() == XalanNode::ELEMENT_NODE)
  +     {
  +             const XalanNamedNodeMap* const  attributeList = 
context->getAttributes();
  +
  +             if(attributeList != 0) 
  +             {
  +                     opPos += 3;
  +
  +                     const unsigned int      nAttrs = 
attributeList->getLength();
  +
  +                     if (nAttrs != 0)
  +                     {
  +                             const NodeTester        theTester(
  +                                                             *this,
  +                                                             
executionContext,
  +                                                             opPos,
  +                                                             argLen,
  +                                                             stepType);
  +
  +                             for(unsigned int j = 0; j < nAttrs; j++)
  +                             {
  +                                     XalanNode* const        theNode = 
attributeList->item(j);
  +                                     assert(theNode != 0 && 
theNode->getNodeType() == XalanNode::ATTRIBUTE_NODE);
  +
  +                                     const eMatchScore       score =
  +                                             theTester(*theNode, 
XalanNode::ATTRIBUTE_NODE);
  +                                             assert(score == 
nodeTest(executionContext, theNode, XalanNode::ATTRIBUTE_NODE, opPos, argLen, 
stepType));
  +
  +                                     if(eMatchScoreNone != score)
  +                                     {
  +                                             
subQueryResults.addNode(theNode);
  +                                     }
  +                             }
  +                     }
  +             }
  +     }
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findChildren(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     XalanNode*      child = context->getFirstChild();
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     if (child != 0)
  +     {
  +             opPos += 3;
  +
  +             const NodeTester        theTester(
  +                                             *this,
  +                                             executionContext,
  +                                             opPos,
  +                                             argLen,
  +                                             stepType);
  +
  +             do
  +             {
  +                     const eMatchScore       score =
  +                                     theTester(*child, child->getNodeType());
  +                                     assert(score == 
nodeTest(executionContext, child, child->getNodeType(), opPos, argLen, 
stepType));
  +
  +                     if(eMatchScoreNone != score)
  +                     {
  +                             subQueryResults.addNode(child);
  +                     }
  +
  +                     child = child->getNextSibling();
  +             } while(0 != child);
  +
  +             subQueryResults.setDocumentOrder();
  +     }
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findDescendants(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     // Perform a pre-order traversal of descendents...
  +     XalanNode*      pos = context;
  +
  +     opPos += 3;
  +
  +     const NodeTester        theTester(
  +                                             *this,
  +                                             executionContext,
  +                                             opPos,
  +                                             argLen,
  +                                             stepType);
  +
  +     do
  +     {                                       
  +             if(stepType == XPathExpression::eFROM_DESCENDANTS_OR_SELF ||
  +                context != pos)
  +             {
  +                     const eMatchScore       score =
  +                             theTester(*pos, pos->getNodeType());
  +                             assert(score == nodeTest(executionContext, pos, 
pos->getNodeType(), opPos, argLen, stepType));
  +
  +                     if(score != eMatchScoreNone)
  +                     {
  +                             subQueryResults.addNode(pos);
  +                     }
  +             }
  +
  +             XalanNode*      nextNode = pos->getFirstChild();
  +
  +             while(0 == nextNode)
  +             {
  +                     if(context == pos)
  +                             break;
  +
  +                     nextNode = pos->getNextSibling();
  +
  +                     if(0 == nextNode)
  +                     {
  +                             pos = DOMServices::getParentOfNode(*pos);
  +
  +                             if(context == pos || pos == 0)
  +                             {
  +                                     nextNode = 0;
  +                                     break;
  +                             }
  +                     }
  +             }
  +
  +             pos = nextNode;
  +     } while(0 != pos);
  +
  +     subQueryResults.setDocumentOrder();
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findFollowing(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     opPos += 3;
  +
  +     // What fun...
  +     XalanDocument* const    doc = context->getOwnerDocument();
  +
  +     XalanNode*                              pos = context;
  +
  +     const NodeTester        theTester(
  +                                     *this,
  +                                     executionContext,
  +                                     opPos,
  +                                     argLen,
  +                                     stepType);
  +
  +     while(0 != pos)
  +     {
  +             XalanNode*      nextNode = 0;
  +
  +             if(pos != context)
  +             {
  +                     const eMatchScore       score =
  +                             theTester(*pos, pos->getNodeType());
  +                             assert(score == nodeTest(executionContext, pos, 
pos->getNodeType(), opPos, argLen, stepType));
  +
  +                     if(eMatchScoreNone != score)
  +                     {
  +                             subQueryResults.addNodeInDocOrder(pos, 
executionContext);
  +                     }
  +
  +                     nextNode = pos->getFirstChild();
  +             }
  +             else
  +             {
  +                     nextNode = 0;
  +             }
  +
  +             while(0 == nextNode)
  +             {
  +                     // This requires some explanation.  pos could be an 
attribute
  +                     // node, so getNextSibling() will always return 0.  In 
that
  +                     // case, I want to continue the search with the first 
child of
  +                     // the owner element, as if attribute nodes are 
children which
  +                     // are always _before_ the first child element.  I 
don't have to
  +                     // consider following attributes, since they _never_ 
match the
  +                     // following axis.
  +                     if (pos->getNodeType() == XalanNode::ATTRIBUTE_NODE)
  +                     {
  +                             assert(DOMServices::getParentOfNode(*pos) != 0);
  +
  +                             nextNode = 
DOMServices::getParentOfNode(*pos)->getFirstChild();
  +                     }
  +                     else
  +                     {
  +                             nextNode = pos->getNextSibling();
  +                     }
  +
  +                     if(0 == nextNode)
  +                     {
  +                             pos = DOMServices::getParentOfNode(*pos);
  +
  +                             if(doc == pos || 0 == pos)
  +                             {
  +                                     nextNode = 0;
  +
  +                                     break;
  +                             }
  +                     }
  +             }
  +
  +             pos = nextNode;
  +     }
  +
  +     subQueryResults.setDocumentOrder();
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findFollowingSiblings(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     XalanNode*      pos = context->getNextSibling();
  +
  +     if (pos != 0)
  +     {
  +             opPos += 3;
  +
  +             const NodeTester        theTester(
  +                                             *this,
  +                                             executionContext,
  +                                             opPos,
  +                                             argLen,
  +                                             stepType);
  +
  +             do
  +             {
  +                     const eMatchScore       score =
  +                                     theTester(*pos, pos->getNodeType());
  +                                     assert(score == 
nodeTest(executionContext, pos, pos->getNodeType(), opPos, argLen, stepType));
  +
  +                     if(eMatchScoreNone != score)
  +                     {
  +                             subQueryResults.addNode(pos);
  +                     }
  +
  +                     pos = pos->getNextSibling();
  +             } while(0 != pos);
  +
  +             subQueryResults.setDocumentOrder();
  +     }
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findPreceeding(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     opPos += 3;
  +
  +     // Ugh.  Reverse document order, no parents, I guess.
  +     XalanDocument* const    doc = context->getOwnerDocument();
  +
  +     XalanNode*                              pos = doc;
  +
  +     // If the context node is an attribute, we need to perform some
  +     // magic to stop the search at the appropriate point, which is when
  +     // we arrive back at the parent.
  +     const bool                              contextIsAttribute =
  +                     context->getNodeType() == XalanNode::ATTRIBUTE_NODE ? 
true : false;
  +
  +     const XalanNode* const  theAttributeContextParent =
  +             contextIsAttribute == true ? 
DOMServices::getParentOfNode(*context) : 0;
  +
  +     const NodeTester        theTester(
  +                                             *this,
  +                                             executionContext,
  +                                             opPos,
  +                                             argLen,
  +                                             stepType);
  +
  +     while(0 != pos)
  +     {
  +             if(context == pos)
  +             {
  +                     break;
  +             }
  +
  +             const eMatchScore       score =
  +                             theTester(*pos, pos->getNodeType());
  +                             assert(score == nodeTest(executionContext, pos, 
pos->getNodeType(), opPos, argLen, stepType));
  +
  +             if(eMatchScoreNone != score)
  +             {
  +                     // Ugh. If I could think a little better tonight, I'm
  +                     // sure there's a better way to check for the parent.
  +                     bool            isParent = false;
  +
  +                     XalanNode*      parent = 
DOMServices::getParentOfNode(*context);
  +
  +                     while(0 != parent)
  +                     {
  +                             if(parent == pos)
  +                             {
  +                                     isParent = true;
  +                                     break;
  +                             }
  +
  +                             parent = DOMServices::getParentOfNode(*parent);
  +                     }
  +
  +                     if(isParent == false)
  +                     {
  +                             subQueryResults.addNode(pos);
  +                     }
  +             }
  +
  +             XalanNode*      nextNode = 0;
  +
  +             // Check to see if we're back at the attribute context node's
  +             // parent, in which case, we should stop.
  +             if (contextIsAttribute == true &&
  +                     pos == theAttributeContextParent)
  +             {
  +                     nextNode = context;
  +             }
  +             else
  +             {
  +                     nextNode = pos->getFirstChild();
  +             }
  +
  +             while(0 == nextNode)
  +             {
  +                     nextNode = pos->getNextSibling();
  +
  +                     if(0 == nextNode)
  +                     {
  +                             pos = DOMServices::getParentOfNode(*pos);
  +
  +                             if(doc == pos)
  +                             {
  +                                     nextNode = 0;
  +                                     break;
  +                             }
  +                     }
  +             }
  +
  +             pos = nextNode;
  +     }
  +
  +     // Now, reverse the order of the nodes, since
  +     // preceeding is a reverse axis, and we searched
  +     // the document from the root to this node.
  +     subQueryResults.reverse();
  +
  +     subQueryResults.setReverseDocumentOrder();
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findPreceedingSiblings(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     XalanNode*      pos = context->getPreviousSibling();
  +
  +     if (pos != 0)
  +     {
  +             opPos += 3;
  +
  +             const NodeTester        theTester(
  +                                             *this,
  +                                             executionContext,
  +                                             opPos,
  +                                             argLen,
  +                                             stepType);
  +
  +             do
  +             {
  +                     const eMatchScore       score = 
  +                             theTester(*pos, pos->getNodeType());
  +                             assert(score == nodeTest(executionContext, pos, 
pos->getNodeType(), opPos, argLen, stepType));
  +
  +                     if(eMatchScoreNone != score)
  +                     {
  +                             subQueryResults.addNode(pos);
  +                     }
  +
  +                     pos = pos->getPreviousSibling();
  +             } while(0 != pos);
  +
  +             subQueryResults.setReverseDocumentOrder();
  +     }
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findNamespace(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const
  +{
  +     assert(context != 0);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     if(context->getNodeType() == XalanNode::ELEMENT_NODE)
  +     {
  +             opPos += 3;
  +
  +             // Look up the element chain until we hit the document, so that 
we
  +             // get all of the attribute/namespace nodes.
  +             const XalanNode* const  theOwnerDocument = 
context->getOwnerDocument();
  +             assert(theOwnerDocument != 0);
  +
  +             const XalanNode*                theCurrentNode = context;
  +
  +             const NodeTester        theTester(
  +                                             *this,
  +                                             executionContext,
  +                                             opPos,
  +                                             argLen,
  +                                             stepType);
  +
  +             do
  +             {
  +                     const XalanNamedNodeMap* const  attributeList =
  +                             theCurrentNode->getAttributes();
  +
  +                     if(attributeList != 0) 
  +                     {
  +                             const unsigned int      nAttrs = 
attributeList->getLength();
  +
  +                             for(unsigned int i = 0; i < nAttrs; ++i)
  +                             {
  +                                     XalanNode* const        attr = 
attributeList->item(i);
  +                                     assert(attr != 0 && attr->getNodeType() 
== XalanNode::ATTRIBUTE_NODE);
  +
  +                                     const XalanDOMString&   theNodeName = 
attr->getNodeName();
  +
  +                                     // This is an optimization to keep 
non-namespace attributes out of
  +                                     // the call to nodeTest().
  +                                     if (startsWith(theNodeName, 
DOMServices::s_XMLNamespaceWithSeparator) == true ||
  +                                             ::equals(theNodeName, 
DOMServices::s_XMLNamespace) == true)
  +                                     {
  +                                             const eMatchScore       score =
  +                                                     theTester(*attr, 
XalanNode::ATTRIBUTE_NODE);
  +                                                     assert(score == 
nodeTest(executionContext, attr, XalanNode::ATTRIBUTE_NODE, opPos, argLen, 
stepType));
  +
  +                                             if(score != eMatchScoreNone)
  +                                             {
  +                                                     
subQueryResults.addNode(attr);
  +                                             }
  +                                     }
  +                             }
  +                     }
  +
  +                     theCurrentNode = theCurrentNode->getParentNode();
  +             } while (theCurrentNode != theOwnerDocument && theCurrentNode 
!= 0);
  +     }
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +int
  +XPath::findNodesOnUnknownAxis(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     /* stepType */,
  +                     MutableNodeRefList&     /* subQueryResults */) const
  +{
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     // $$ ToDO: Can we reduce this to some call on the
  +     // XPathExpression interface?
  +     const int       argLen =
  +             currentExpression.getOpCodeMapValue(opPos + 
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
  +
  +     executionContext.error(TranscodeFromLocalCodePage("Unknown axis!"), 
context, getLocator());
  +
  +     return argLen + 3;
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::nodeTest(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context,
  +                     XalanNode::NodeType             nodeType,
  +                     int                                     opPos,
  +                     int                                     argLen,
  +                     int                                     stepType) const
  +{
  +     assert(context->getNodeType() == nodeType);
  +
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     eMatchScore             score = eMatchScoreNone;
  +
  +     const int       testType = currentExpression.getOpCodeMapValue(opPos);
  +
  +     switch(testType)
  +     {
  +     case XPathExpression::eNODETYPE_COMMENT:
  +             if (XalanNode::COMMENT_NODE == nodeType)
  +             {
  +                     score = eMatchScoreNodeTest;
  +             }
  +             break;
  +
  +     case XPathExpression::eNODETYPE_TEXT:
  +             if ((XalanNode::CDATA_SECTION_NODE == nodeType ||
  +                      XalanNode::TEXT_NODE == nodeType) &&
  +                     executionContext.shouldStripSourceNode(*context) == 
false)
  +             {
  +                       score = eMatchScoreNodeTest;
  +             }
  +       break;
  +
  +     case XPathExpression::eNODETYPE_PI:
  +             if(XalanNode::PROCESSING_INSTRUCTION_NODE == nodeType)
  +             {
  +                     if(argLen == 1)
  +                     {
  +                             score = eMatchScoreNodeTest;
  +                     }
  +                     else if(argLen == 2)
  +                     {
  +                             opPos++;
  +
  +                             const int                               
tokenPosition =
  +                                     
currentExpression.getOpCodeMapValue(opPos);
  +
  +                             const XObject* const    name =
  +                                     
currentExpression.getToken(tokenPosition);
  +                             assert(name != 0);
  +
  +                             if (::equals(context->getNodeName(), 
name->str()) == true)
  +                             {
  +                                     score = eMatchScoreQName;
  +                             }
  +                     }
  +                     else
  +                     {
  +                             
executionContext.error(TranscodeFromLocalCodePage("Arg length of 
processing-instruction() node test is incorrect!"), context, getLocator());
  +                     }
  +             }
  +
  +             break;
  +
  +     case XPathExpression::eNODETYPE_NODE:
  +             if (nodeType == XalanNode::CDATA_SECTION_NODE ||
  +                     nodeType == XalanNode::TEXT_NODE)
  +             {
  +                     if (executionContext.shouldStripSourceNode(*context) == 
false)
  +                     {
  +                             score = eMatchScoreNodeTest;
  +                     }
  +             }
  +             else
  +             {
  +                     score = eMatchScoreNodeTest;
  +             }
  +             break;
  +
  +     case XPathExpression::eNODETYPE_ROOT:
  +             if (XalanNode::DOCUMENT_FRAGMENT_NODE == nodeType ||
  +                     XalanNode::DOCUMENT_NODE == nodeType)
  +             {
  +                     score =  eMatchScoreOther;
  +             }
  +             break;
  +
  +     case XPathExpression::eNODENAME:
  +             {
  +                     opPos++;
  +
  +                     if (nodeType == XalanNode::ATTRIBUTE_NODE || nodeType 
== XalanNode::ELEMENT_NODE)
  +                     {
  +                             bool                                    test = 
false;
  +
  +                             int                                     
queueIndex = currentExpression.getOpCodeMapValue(opPos);
  +
  +                             const XalanDOMString&   targetNS = queueIndex 
>= 0 ?
  +                                                                             
currentExpression.getToken(queueIndex)->str() :
  +                                                                             
        s_emptyString;
  +
  +                             opPos++;
  +
  +                             // From the draft: "Two expanded names are 
equal if they 
  +                             // have the same local part, and either both 
have no URI or 
  +                             // both have the same URI."
  +                             // "A node test * is true for any node of the 
principal node type. 
  +                             // For example, child::* will select all 
element children of the 
  +                             // context node, and attribute::* will select 
all attributes of 
  +                             // the context node."
  +                             // "A node test can have the form NCName:*. In 
this case, the prefix 
  +                             // is expanded in the same way as with a QName 
using the context 
  +                             // namespace declarations. The node test will 
be true for any node 
  +                             // of the principal type whose expanded name 
has the URI to which 
  +                             // the prefix expands, regardless of the local 
part of the name."
  +                             const bool      isTotallyWild =
  +                                                     0 == length(targetNS) &&
  +                                                     
currentExpression.getOpCodeMapValue(opPos) == XPathExpression::eELEMWILDCARD;
  +
  +                             bool            didMatchNS = false;
  +
  +                             if(isTotallyWild == false)
  +                             {
  +                                     const XalanDOMString&   contextNS = 
DOMServices::getNamespaceOfNode(*context);
  +
  +                                     if(0 != length(targetNS) && 0 != 
length(contextNS))
  +                                     {
  +                                             test = ::equals(contextNS, 
targetNS);
  +
  +                                             didMatchNS = true;
  +                                     }
  +                                     else
  +                                     {
  +                                             test = 
XPathExpression::eELEMWILDCARD == queueIndex || 
  +                                                (0 == length(contextNS) && 0 
== length(targetNS));
  +                                     }
  +                             }
  +                             else
  +                             {
  +                                     test = true;
  +                             }
  +
  +                             queueIndex = 
currentExpression.getOpCodeMapValue(opPos);
  +
  +                             if(test == true)
  +                             {
  +                                     switch(nodeType)
  +                                     {
  +                                     case XalanNode::ATTRIBUTE_NODE:
  +                                             if(stepType == 
XPathExpression::eFROM_ATTRIBUTES ||
  +                                                     stepType == 
XPathExpression::eFROM_NAMESPACE)
  +                                             {
  +                                                     
assert(context->getNodeType() == XalanNode::ATTRIBUTE_NODE);
  +
  +                                                     const XalanDOMString&   
attrName =
  +                                                                             
context->getNodeName();
  +
  +                                                     const bool              
                isNamespace =
  +                                                                     
startsWith(attrName, DOMServices::s_XMLNamespaceWithSeparator) ||
  +                                                                     
::equals(attrName, DOMServices::s_XMLNamespace);
  +
  +                                                     
if(XPathExpression::eELEMWILDCARD == queueIndex)
  +                                                     {
  +                                                             if(stepType == 
XPathExpression::eFROM_ATTRIBUTES)
  +                                                             {
  +                                                                     if 
(isNamespace == false)
  +                                                                     {
  +                                                                             
score = eMatchScoreNodeTest;
  +                                                                     }
  +                                                             }
  +                                                             else
  +                                                             {
  +                                                                     if 
(isNamespace == true)
  +                                                                     {
  +                                                                             
score = eMatchScoreNodeTest;
  +                                                                     }
  +                                                             }
  +                                                     }
  +                                                     else
  +                                                     {
  +                                                             if(stepType == 
XPathExpression::eFROM_ATTRIBUTES)
  +                                                             {
  +                                                                     if 
(isNamespace == false)
  +                                                                     {
  +                                                                             
assert(queueIndex >= 0);
  +
  +                                                                             
const XalanDOMString&   targetLocalName =
  +                                                                             
                                        
currentExpression.getToken(queueIndex)->str();
  +
  +                                                                             
const XalanDOMString&   localAttrName =
  +                                                                             
                DOMServices::getLocalNameOfNode(*context);
  +
  +                                                                             
if (::equals(localAttrName, targetLocalName) == true)
  +                                                                             
{
  +                                                                             
        score = eMatchScoreQName;
  +                                                                             
}
  +                                                                     }
  +                                                             }
  +                                                             else
  +                                                             {
  +                                                                     if 
(isNamespace == true)
  +                                                                     {
  +                                                                             
const XalanAttr* const  theAttrNode =
  +#if defined(XALAN_OLD_STYLE_CASTS)
  +                                                                             
        (const XalanAttr*)context;
  +#else
  +                                                                             
        static_cast<const XalanAttr*>(context);
  +#endif
  +                                                                             
assert(theAttrNode != 0);
  +
  +                                                                             
const XalanDOMString&   theNamespace =
  +                                                                             
                        theAttrNode->getValue();
  +
  +                                                                             
assert(queueIndex >= 0);
  +
  +                                                                             
const XalanDOMString&   targetLocalName =
  +                                                                             
                                        
currentExpression.getToken(queueIndex)->str();
  +
  +                                                                             
if (::equals(theNamespace, targetLocalName) == true)
  +                                                                             
{
  +                                                                             
        score = eMatchScoreQName;
  +                                                                             
}
  +                                                                     }
  +                                                             }
  +                                                     }
  +                                             }
  +                                             break;
  +
  +                                     case XalanNode::ELEMENT_NODE:
  +                                             if(stepType != 
XPathExpression::eFROM_ATTRIBUTES)
  +                                             {
  +                                                     
if(XPathExpression::eELEMWILDCARD == queueIndex)
  +                                                     {
  +                                                             score = 
didMatchNS == true ?
  +                                                                     
eMatchScoreNSWild : eMatchScoreNodeTest;
  +                                                     }
  +                                                     else
  +                                                     {
  +                                                             
assert(queueIndex >= 0);
  +
  +                                                             const 
XalanDOMString&   targetLocalName =
  +                                                                             
                                        
currentExpression.getToken(queueIndex)->str();
  +
  +                                                             if 
(::equals(DOMServices::getLocalNameOfNode(*context),
  +                                                                             
   targetLocalName) == true)
  +                                                             {
  +                                                                     score = 
eMatchScoreQName;
  +                                                             }
  +                                                     }
  +                                             }
  +                                             break;
  +
  +                                     default:
  +                                             // Trying to match on anything 
else causes nasty bugs.
  +                                             break;
  +                                     } // end switch(nodeType)
  +                             } // end if(test)
  +                     } // end if (nodeType == XalanNode::ATTRIBUTE_NODE || 
nodeType == XalanNode::ELEMENT_NODE)
  +             } // end case XPathExpression::eNODENAME
  +             break;
  +
  +     default:
  +             break;
  +     } // end switch(testType)
  +
  +     return score;
  +}
  +
  +
  +
  +void
  +XPath::predicates(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              /* context */, 
  +                     int                                     opPos,
  +                     MutableNodeRefList&     subQueryResults,
  +                     int&                                    
endPredicatesPos) const
  +{
  +     const XPathExpression&  currentExpression = getExpression();
  +
  +     int     nextStepType =
  +                     currentExpression.getOpCodeMapValue(opPos);
  +
  +     while(XPathExpression::eOP_PREDICATE == nextStepType)
  +     {
  +             NodeRefListBase::size_type                      i = 0;
  +
  +             const NodeRefListBase::size_type        theLength = 
subQueryResults.getLength();
  +
  +             while(i < theLength)
  +             {
  +                     XalanNode* const        theNode = 
subQueryResults.item(i);
  +                     assert(theNode != 0);
  +
  +                     const XObjectPtr                pred(predicate(theNode, 
opPos, executionContext));
  +                     assert(pred.get() != 0);
  +
  +                     // Remove any node that doesn't satisfy the predicate.
  +                     if(XObject::eTypeNumber == pred->getType() &&
  +                                     i + 1 != pred->num() ||
  +                        pred->boolean() == false)
  +                     {
  +                             // Set the node to 0.  After we're done,
  +                             // we'll clear it out.
  +                             subQueryResults.setNode(i, 0);
  +                     }
  +
  +                     ++i;
  +             }
  +
  +             // Clear out any null entries...
  +             subQueryResults.clearNulls();
  +
  +             opPos = currentExpression.getNextOpCodePosition(opPos);
  +
  +             nextStepType = currentExpression.getOpCodeMapValue(opPos);
  +
  +             if(XPathExpression::eOP_PREDICATE == nextStepType)
  +             {
  +                     executionContext.setContextNodeList(subQueryResults);
  +
  +                     // Don't break, loop 'till end so that opPos will be 
set to end.
  +                     // if(0 == subQueryResults.getLength())
  +                     //      break;
  +             }
  +     }
  +
  +     endPredicatesPos = opPos;
  +}
  +
  +
  +
  +inline const XalanDOMString*
  +getStringFromTokenQueue(
  +                     const XPathExpression&  expression,
  +                     int                                             opPos)
  +{
  +     const int       tokenPosition =
  +                             expression.getOpCodeMapValue(opPos);
  +
  +     if (tokenPosition < 0)
  +     {
  +             return 0;
  +     }
  +     else
  +     {
  +             const XObject* const    token =
  +                                     expression.getToken(tokenPosition);
  +             assert(token != 0);
  +
  +             return &token->str();
  +     }
  +}
  +
  +
  +
  +XPath::NodeTester::NodeTester(
  +                     const XPath&                    xpath,
  +                     XPathExecutionContext&  executionContext,
  +                     int                                     opPos,
  +                     int                                     argLen,
  +                     int                                     stepType) :
  +     m_executionContext(executionContext),
  +     m_targetNamespace(0),
  +     m_targetLocalName(0),
  +     m_testFunction(0)
  +{
  +     const XPathExpression&  theExpression = xpath.getExpression();
  +
  +     switch(theExpression.getOpCodeMapValue(opPos))
  +     {
  +     case XPathExpression::eNODETYPE_COMMENT:
  +             m_testFunction = &NodeTester::testComment;
  +             break;
  +
  +     case XPathExpression::eNODETYPE_TEXT:
  +             m_testFunction = &NodeTester::testText;
  +             break;
  +
  +     case XPathExpression::eNODETYPE_PI:
  +             if (argLen == 1)
  +             {
  +                     m_testFunction = &NodeTester::testPI;
  +             }
  +             else if(argLen == 2)
  +             {
  +                     m_testFunction = &NodeTester::testPIName;
  +
  +                     m_targetLocalName = getStringFromTokenQueue(
  +                             theExpression,
  +                             opPos + 1);
  +             }
  +             else
  +             {
  +                     executionContext.error(TranscodeFromLocalCodePage("Arg 
length of processing-instruction() node test is incorrect!"), 0, 
xpath.getLocator());
  +             }
  +             break;
  +
  +     case XPathExpression::eNODETYPE_NODE:
  +             m_testFunction = &NodeTester::testNode;
  +             break;
  +
  +     case XPathExpression::eNODETYPE_ROOT:
  +             m_testFunction = &NodeTester::testRoot;
  +             break;
  +
  +     case XPathExpression::eNODENAME:
  +             {
  +                     bool    isTotallyWild = false;
  +
  +                     m_targetNamespace = getStringFromTokenQueue(
  +                                     theExpression,
  +                                     opPos + 1);
  +
  +                     if (m_targetNamespace == 0 &&
  +                             theExpression.getOpCodeMapValue(opPos + 2) == 
XPathExpression::eELEMWILDCARD)
  +                     {
  +                             isTotallyWild = true;
  +                     }
  +                     else
  +                     {
  +                             m_targetLocalName = getStringFromTokenQueue(
  +                                     theExpression,
  +                                     opPos + 2);
  +                     }
  +
  +                     if(stepType == XPathExpression::eFROM_ATTRIBUTES)
  +                     {
  +                             if (isTotallyWild == true)
  +                             {
  +                                     m_testFunction = 
&NodeTester::testAttributeTotallyWild;
  +                             }
  +                             else if (m_targetNamespace == 0)
  +                             {
  +                                     assert(m_targetLocalName != 0);
  +
  +                                     m_testFunction = 
&NodeTester::testAttributeNCName;
  +                             }
  +                             else if (m_targetLocalName == 0)
  +                             {
  +                                     assert(m_targetNamespace != 0);
  +
  +                                     m_testFunction = 
&NodeTester::testAttributeNamespaceOnly;
  +                             }
  +                             else
  +                             {
  +                                     assert(m_targetNamespace != 0 && 
m_targetLocalName != 0);
  +
  +
  +                                     m_testFunction = 
&NodeTester::testAttributeQName;
  +                             }
  +                     }
  +                     else if (stepType == XPathExpression::eFROM_NAMESPACE)
  +                     {
  +                             if (isTotallyWild == true)
  +                             {
  +                                     m_testFunction = 
&NodeTester::testNamespaceTotallyWild;
  +                             }
  +                             else
  +                             {
  +                                     m_testFunction = 
&NodeTester::testNamespaceNCName;
  +                             }
  +                     }
  +                     else
  +                     {
  +                             if (isTotallyWild == true)
  +                             {
  +                                     m_testFunction = 
&NodeTester::testElementTotallyWild;
  +                             }
  +                             else if (m_targetNamespace == 0)
  +                             {
  +                                     m_testFunction = 
&NodeTester::testElementNCName;
  +                             }
  +                             else if (m_targetLocalName == 0)
  +                             {
  +                                     assert(m_targetNamespace != 0);
  +
  +                                     m_testFunction = 
&NodeTester::testElementNamespaceOnly;
  +                             }
  +                             else
  +                             {
  +                                     assert(m_targetNamespace != 0 && 
m_targetLocalName != 0);
  +
  +                                     m_testFunction = 
&NodeTester::testElementQName;
  +                             }
  +                     }
  +             }
  +             break;
  +
  +     default:
  +             m_testFunction = &NodeTester::testDefault;
  +             break;
  +     }
  +
  +     assert(m_testFunction != 0);
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testComment(
  +                     const XalanNode&                /* context */,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     if (XalanNode::COMMENT_NODE == nodeType)
  +     {
  +             return eMatchScoreNodeTest;
  +     }
  +     else
  +     {
  +             return eMatchScoreNone;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testText(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     if ((XalanNode::CDATA_SECTION_NODE == nodeType || XalanNode::TEXT_NODE 
== nodeType) &&
  +              shouldStripSourceNode(context) == false)
  +     {
  +             return eMatchScoreNodeTest;
  +     }
  +     else
  +     {
  +             return eMatchScoreNone;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testPI(
  +                     const XalanNode&                /* context */,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     if (XalanNode::PROCESSING_INSTRUCTION_NODE == nodeType)
  +     {
  +             return eMatchScoreNodeTest;
  +     }
  +     else
  +     {
  +             return eMatchScoreNone;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testPIName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     assert(m_targetLocalName != 0);
  +
  +     if (XalanNode::PROCESSING_INSTRUCTION_NODE == nodeType &&
  +             ::equals(context.getNodeName(), *m_targetLocalName) == true)
  +     {
  +             return eMatchScoreQName;
  +     }
  +     else
  +     {
  +             return eMatchScoreNone;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testNode(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     if ((nodeType != XalanNode::CDATA_SECTION_NODE && nodeType != 
XalanNode::TEXT_NODE) ||
  +             shouldStripSourceNode(context) == false)
  +     {
  +             return eMatchScoreNodeTest;
  +     }
  +     else
  +     {
  +             return eMatchScoreNone;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testRoot(
  +                     const XalanNode&                /* context */,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     if (XalanNode::DOCUMENT_FRAGMENT_NODE == nodeType ||
  +             XalanNode::DOCUMENT_NODE == nodeType)
  +     {
  +             return eMatchScoreOther;
  +     }
  +     else
  +     {
  +             return eMatchScoreNone;
  +     }
  +}
  +
  +
  +
  +inline bool
  +isNamespaceDeclaration(const XalanNode&              theAttributeNode)
  +{
  +     assert(theAttributeNode.getNodeType() == XalanNode::ATTRIBUTE_NODE);
  +
  +#if defined(XALAN_OLD_STYLE_CASTS)
  +     return DOMServices::isNamespaceDeclaration((const 
XalanAttr&)theAttributeNode);
  +#else
  +     return DOMServices::isNamespaceDeclaration(static_cast<const 
XalanAttr&>(theAttributeNode));
  +#endif
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testAttributeNCName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     assert(m_targetNamespace == 0 && m_targetLocalName != 0);
  +
  +     if (XalanNode::ATTRIBUTE_NODE != nodeType ||
  +             isNamespaceDeclaration(context) == true ||
  +             matchLocalName(context) == false)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             return eMatchScoreQName;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testAttributeQName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     assert(m_targetNamespace != 0 && m_targetLocalName != 0);
  +
  +     if (XalanNode::ATTRIBUTE_NODE != nodeType ||
  +             isNamespaceDeclaration(context) == true ||
  +             matchLocalNameAndNamespaceURI(context) == false)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             return eMatchScoreQName;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testAttributeNamespaceOnly(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     assert(m_targetNamespace != 0 && m_targetLocalName == 0);
  +
  +     if (XalanNode::ATTRIBUTE_NODE != nodeType ||
  +             isNamespaceDeclaration(context) == true ||
  +             matchNamespaceURI(context) == false)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             return eMatchScoreNodeTest;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testAttributeTotallyWild(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     if (XalanNode::ATTRIBUTE_NODE != nodeType ||
  +             isNamespaceDeclaration(context) == true)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             return eMatchScoreNodeTest;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testElementNCName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     assert(m_targetNamespace == 0 && m_targetLocalName != 0);
  +
  +     if (XalanNode::ELEMENT_NODE != nodeType ||
  +             matchLocalName(context) == false)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             return eMatchScoreQName;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testElementQName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     assert(m_targetNamespace != 0 && m_targetLocalName != 0);
  +
  +     if (XalanNode::ELEMENT_NODE != nodeType ||
  +             matchLocalNameAndNamespaceURI(context) == false)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             return eMatchScoreQName;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testElementNamespaceOnly(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     assert(m_targetNamespace != 0 && m_targetLocalName == 0);
  +
  +     if (XalanNode::ELEMENT_NODE != nodeType ||
  +             matchNamespaceURI(context) == false)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             return eMatchScoreNSWild;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testElementTotallyWild(
  +                     const XalanNode&                /* context */,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     assert(m_targetNamespace == 0 && m_targetLocalName == 0);
  +
  +     if (XalanNode::ELEMENT_NODE != nodeType)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             return eMatchScoreNodeTest;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testNamespaceNCName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     assert(m_targetNamespace == 0 && m_targetLocalName != 0);
  +
  +     if (XalanNode::ATTRIBUTE_NODE != nodeType ||
  +             isNamespaceDeclaration(context) == false ||
  +             matchNamespace(context) == false)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             return eMatchScoreQName;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testNamespaceTotallyWild(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +{
  +     assert(m_targetNamespace == 0 && m_targetLocalName == 0);
  +
  +     if (XalanNode::ATTRIBUTE_NODE != nodeType ||
  +             isNamespaceDeclaration(context) == false)
  +     {
  +             return eMatchScoreNone;
  +     }
  +     else
  +     {
  +             return eMatchScoreNodeTest;
  +     }
  +}
  +
  +
  +
  +XPath::eMatchScore
  +XPath::NodeTester::testDefault(
  +                     const XalanNode&                /* context */,
  +                     XalanNode::NodeType             /* nodeType */) const
  +{
  +     return eMatchScoreNone;
  +}
  +
  +
  +
  +bool
  +XPath::NodeTester::matchLocalName(const XalanNode&   context) const
  +{
  +     assert(m_targetLocalName != 0);
  +
  +     return length(context.getNamespaceURI()) == 0 &&
  +             ::equals(DOMServices::getLocalNameOfNode(context), 
*m_targetLocalName);
  +}
  +
  +
  +
  +bool
  +XPath::NodeTester::matchNamespaceURI(const XalanNode&        context) const
  +{
  +     assert(m_targetNamespace != 0);
  +
  +     return ::equals(context.getNamespaceURI(), *m_targetNamespace);
  +}
  +
  +
  +
  +bool
  +XPath::NodeTester::matchLocalNameAndNamespaceURI(const XalanNode&    
context) const
  +{
  +     assert(m_targetNamespace != 0 && m_targetLocalName != 0);
  +
  +     return ::equals(DOMServices::getLocalNameOfNode(context), 
*m_targetLocalName) == true &&
  +             ::equals(context.getNamespaceURI(), *m_targetNamespace) == true;
  +}
  +
  +
  +
  +bool
  +XPath::NodeTester::matchNamespace(const XalanNode&   context) const
  +{
  +     assert(m_targetLocalName != 0);
  +
  +     return ::equals(context.getNodeValue(), *m_targetLocalName);
  +}
  +
  +
  +
  +bool
  +XPath::NodeTester::shouldStripSourceNode(const XalanNode&    context) const
  +{
  +     assert(context.getNodeType() == XalanNode::CDATA_SECTION_NODE ||
  +                context.getNodeType() == XalanNode::TEXT_NODE);
  +
  +     return m_executionContext.shouldStripSourceNode(context);
   }
   
   
  
  
  
  1.30      +319 -0    xml-xalan/c/src/XPath/XPath.hpp
  
  Index: XPath.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XPath.hpp,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- XPath.hpp 2001/09/14 20:06:26     1.29
  +++ XPath.hpp 2001/10/24 15:44:51     1.30
  @@ -813,6 +813,323 @@
                eDefaultTargetStringsSize = 5
        };
   
  +     const XObjectPtr
  +     locationPath(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode&                              context, 
  +                     int                                     opPos) const;
  +
  +     eMatchScore
  +     locationPathPattern(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode&                              context, 
  +                     int                                     opPos) const;
  +
  +     class NodeTester
  +     {
  +     public:
  +
  +             NodeTester(
  +                     const XPath&                    xpath,
  +                     XPathExecutionContext&  executionContext,
  +                     int                                     opPos,
  +                     int                                     argLen,
  +                     int                                     stepType);
  +
  +             eMatchScore
  +             operator()(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const
  +             {
  +                     assert(context.getNodeType() == nodeType);
  +
  +                     return (this->*m_testFunction)(context, nodeType);
  +             }
  +
  +     private:
  +
  +             typedef eMatchScore (NodeTester::*MemberFunctionPtr)(const 
XalanNode&, XalanNode::NodeType) const;
  +
  +
  +             eMatchScore
  +             testComment(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testText(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testPI(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testPIName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testNode(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testRoot(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testAttributeNCName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testAttributeQName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testAttributeNamespaceOnly(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testAttributeTotallyWild(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testElementNCName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testElementQName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testElementNamespaceOnly(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testElementTotallyWild(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testNamespaceNCName(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testNamespaceTotallyWild(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             eMatchScore
  +             testDefault(
  +                     const XalanNode&                context,
  +                     XalanNode::NodeType             nodeType) const;
  +
  +             bool
  +             matchLocalName(const XalanNode&         context) const;
  +
  +             bool
  +             matchNamespaceURI(const XalanNode&      context) const;
  +
  +             bool
  +             matchLocalNameAndNamespaceURI(const XalanNode&  context) const;
  +
  +             bool
  +             matchNamespace(const XalanNode&         context) const;
  +
  +             bool
  +             shouldStripSourceNode(const XalanNode&  context) const;
  +
  +             // Data members...
  +             XPathExecutionContext&  m_executionContext;
  +
  +             const XalanDOMString*   m_targetNamespace;
  +
  +             const XalanDOMString*   m_targetLocalName;
  +
  +             MemberFunctionPtr               m_testFunction;
  +     };
  +
  +protected:
  +
  +     void
  +     step(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     MutableNodeRefList&             queryResults) const;
  +
  +     /**
  +      * Execute a step in a location path.
  +      *
  +      * @param xpath The xpath that is executing
  +      * @param context The current source tree context node
  +      * @param opPos The current position in the xpath operation map array
  +      * @param scoreHolder a reference to an eMatchScore to receive
  +      * the result.
  +      * @return the last matched context node
  +      */
  +     XalanNode*
  +     stepPattern(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     eMatchScore&                    scoreHolder) const;
  +
  +     int
  +     findNodeSet(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findRoot(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findParent(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findSelf(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findAncestors(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findAncestorsOrSelf(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findAttributes(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findChildren(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findDescendants(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findFollowing(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findFollowingSiblings(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findPreceeding(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findPreceedingSiblings(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findNamespace(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     int
  +     findNodesOnUnknownAxis(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     int                                     stepType,
  +                     MutableNodeRefList&     subQueryResults) const;
  +
  +     eMatchScore
  +     nodeTest(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context,
  +                     XalanNode::NodeType             nodeType,
  +                     int                                     opPos,
  +                     int                                     argLen,
  +                     int                                     stepType) const;
  +
  +     void
  +     predicates(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              context, 
  +                     int                                     opPos,
  +                     MutableNodeRefList&     subQueryResults,
  +                     int&                                    
endPredicatesPos) const;
  +
  +     eMatchScore
  +     handleFoundIndex(
  +                     XPathExecutionContext&  executionContext,
  +                     XalanNode*                              localContext,
  +                     int                                     startOpPos) 
const;
  +
        // Data members...
   
        /**
  @@ -840,6 +1157,8 @@
         *
         */
        static FunctionTableType                        s_functions;
  +
  +     static const XalanDOMString                     s_emptyString;
   };
   
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to