dbertoni 01/08/05 18:39:30
Modified: c/src/XPath SimpleNodeLocator.cpp SimpleNodeLocator.hpp
Log:
Implemented new NodeTester class.
Revision Changes Path
1.42 +842 -189 xml-xalan/c/src/XPath/SimpleNodeLocator.cpp
Index: SimpleNodeLocator.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/SimpleNodeLocator.cpp,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -r1.41 -r1.42
--- SimpleNodeLocator.cpp 2001/07/21 05:35:15 1.41
+++ SimpleNodeLocator.cpp 2001/08/06 01:39:29 1.42
@@ -129,17 +129,17 @@
xpath.getExpression();
// int endStep = xpath.getNextOpPos(opPos);
- const int stepType =
+ const int stepType =
currentExpression.getOpCodeMapValue(opPos);
- int argLen = 0;
+ int argLen = 0;
typedef XPathExecutionContext::BorrowReturnMutableNodeRefList
BorrowReturnMutableNodeRefList;
BorrowReturnMutableNodeRefList subQueryResults(executionContext);
- bool shouldReorder = false;
- bool continueStepRecursion = true;
+ bool shouldReorder = false;
+ bool continueStepRecursion = true;
switch(stepType)
{
@@ -431,16 +431,18 @@
(prevStepType ==
XPathExpression::eMATCH_ANY_ANCESTOR ||
prevStepType ==
XPathExpression::eMATCH_ANY_ANCESTOR_WITH_PREDICATE))
{
+ const NodeTester theTester(
+ xpath,
+
executionContext,
+ opPos,
+ argLen,
+
stepType);
+
while(0 != context)
{
- score = nodeTest(
- xpath,
- executionContext,
- context,
- context->getNodeType(),
- opPos,
- argLen,
- stepType);
+ score =
+ theTester(*context,
context->getNodeType());
+ assert(score ==
nodeTest(xpath, executionContext, context, context->getNodeType(), opPos,
argLen, stepType));
if(XPath::eMatchScoreNone !=
score)
break;
@@ -460,14 +462,21 @@
currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
opPos += 3;
+
+ score = NodeTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+
XPathExpression::eFROM_ATTRIBUTES)(*context, context->getNodeType());
- score = nodeTest(xpath,
+ assert(score == nodeTest(xpath,
executionContext,
context,
context->getNodeType(),
opPos,
argLen,
-
XPathExpression::eFROM_ATTRIBUTES);
+
XPathExpression::eFROM_ATTRIBUTES));
}
break;
@@ -485,9 +494,17 @@
{
opPos += 3;
+ const NodeTester theTester(
+ xpath,
+
executionContext,
+ opPos,
+ argLen,
+
stepType);
+
for(;;)
{
- score = nodeTest(xpath,
executionContext, context, nodeType, opPos, argLen, stepType);
+ score = theTester(*context, nodeType);
+ assert(score == nodeTest(xpath,
executionContext, context, nodeType, opPos, argLen, stepType));
if(XPath::eMatchScoreNone != score)
break;
@@ -516,7 +533,20 @@
{
opPos += 3;
- score = nodeTest(xpath, executionContext,
context, nodeType, opPos, argLen, stepType);
+ score = NodeTester(
+ xpath,
+
executionContext,
+ opPos,
+ argLen,
+
XPathExpression::eMATCH_IMMEDIATE_ANCESTOR)(*context, nodeType);
+
+ assert(score == nodeTest(xpath,
+
executionContext,
+ context,
+ nodeType,
+ opPos,
+ argLen,
+
XPathExpression::eMATCH_IMMEDIATE_ANCESTOR));
}
}
break;
@@ -684,15 +714,15 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
+ assert(context != 0);
+
const XPathExpression& currentExpression =
- xpath.getExpression();
+ xpath.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;
+ currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
XalanNode* const theParent =
DOMServices::getParentOfNode(*context);
@@ -700,13 +730,17 @@
{
if(argLen > 0)
{
- const XPath::eMatchScore score = nodeTest(xpath,
-
executionContext,
-
theParent,
-
theParent->getNodeType(),
-
opPos,
-
argLen,
-
stepType);
+ opPos += 3;
+
+ const NodeTester theTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+ stepType);
+
+ const XPath::eMatchScore score =
theTester(*theParent, theParent->getNodeType());
+ assert(score == nodeTest(xpath, executionContext,
theParent, theParent->getNodeType(), opPos, argLen, stepType));
if(XPath::eMatchScoreNone != score)
{
@@ -735,6 +769,8 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
+ assert(context != 0);
+
const XPathExpression& currentExpression =
xpath.getExpression();
@@ -742,28 +778,31 @@
// XPathExpression interface?
const int argLen =
currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
-
- opPos += 3;
- if(argLen > 0)
+ if(argLen == 0)
+ {
+ subQueryResults.addNode(context);
+ }
+ else
{
- const XPath::eMatchScore score = nodeTest(xpath,
-
executionContext,
-
context,
-
context->getNodeType(),
-
opPos,
-
argLen,
-
stepType);
+ opPos += 3;
+ const NodeTester theTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+ stepType);
+
+ const XPath::eMatchScore score =
+ theTester(*context, context->getNodeType());
+ assert(score == nodeTest(xpath, executionContext,
context, context->getNodeType(), opPos, argLen, stepType));
+
if(XPath::eMatchScoreNone != score)
{
subQueryResults.addNode(context);
}
}
- else
- {
- subQueryResults.addNode(context);
- }
subQueryResults.setDocumentOrder();
@@ -781,39 +820,46 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
- const XPathExpression& currentExpression =
- xpath.getExpression();
+ assert(context != 0);
+
+ context = DOMServices::getParentOfNode(*context);
- XalanNode* contextNode =
- DOMServices::getParentOfNode(*context);
+ const XPathExpression& currentExpression =
+ xpath.getExpression();
// $$ ToDO: Can we reduce this to some call on the
// XPathExpression interface?
const int argLen =
- currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
+ currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
- opPos += 3;
-
- while(0 != contextNode)
+ if (context != 0)
{
- const XPath::eMatchScore score = nodeTest(xpath,
-
executionContext,
-
contextNode,
-
contextNode->getNodeType(),
-
opPos,
-
argLen,
-
stepType);
+ opPos += 3;
- if(XPath::eMatchScoreNone != score)
+ const NodeTester theTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+ stepType);
+
+ do
{
- subQueryResults.addNode(contextNode);
- }
+ const XPath::eMatchScore score =
+ theTester(*context, context->getNodeType());
+ assert(score == nodeTest(xpath,
executionContext, context, context->getNodeType(), opPos, argLen, stepType));
- contextNode = DOMServices::getParentOfNode(*contextNode);
- }
+ if(XPath::eMatchScoreNone != score)
+ {
+ subQueryResults.addNode(context);
+ }
- subQueryResults.setReverseDocumentOrder();
+ context = DOMServices::getParentOfNode(*context);
+ } while(0 != context);
+ subQueryResults.setReverseDocumentOrder();
+ }
+
return argLen + 3;
}
@@ -828,13 +874,11 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
- // $$ ToDO: Can this function be reduced to calling
- // findSelf() and findAncestors()? I would think so...
+ assert(context != 0);
const XPathExpression& currentExpression =
xpath.getExpression();
- XalanNode* contextNode = context;
// $$ ToDO: Can we reduce this to some call on the
// XPathExpression interface?
@@ -843,23 +887,26 @@
opPos += 3;
- while(0 != contextNode)
- {
- const XPath::eMatchScore score = nodeTest(xpath,
-
executionContext,
-
contextNode,
-
contextNode->getNodeType(),
-
opPos,
-
argLen,
-
stepType);
+ const NodeTester theTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+ stepType);
+
+ do
+ {
+ const XPath::eMatchScore score =
+ theTester(*context, context->getNodeType());
+ assert(score == nodeTest(xpath,
executionContext, context, context->getNodeType(), opPos, argLen, stepType));
if(XPath::eMatchScoreNone != score)
{
- subQueryResults.addNode(contextNode);
+ subQueryResults.addNode(context);
}
- contextNode = DOMServices::getParentOfNode(*contextNode);
- }
+ context = DOMServices::getParentOfNode(*context);
+ } while(0 != context);
subQueryResults.setReverseDocumentOrder();
@@ -877,47 +924,48 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
+ assert(context != 0);
+
const XPathExpression& currentExpression =
- xpath.getExpression();
+ xpath.getExpression();
// $$ ToDO: Can we reduce this to some call on the
// XPathExpression interface?
const int argLen =
- currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
+ currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
- if(0 != context && context->getNodeType() == XalanNode::ELEMENT_NODE)
+ if(context->getNodeType() == XalanNode::ELEMENT_NODE)
{
- const XalanElement* const e =
-#if defined(XALAN_OLD_STYLE_CASTS)
- (const XalanElement*)context;
-#else
- static_cast<const
XalanElement*>(context);
-#endif
+ const XalanNamedNodeMap* const attributeList =
context->getAttributes();
- const XalanNamedNodeMap* const attributeList =
e->getAttributes();
-
if(attributeList != 0)
{
opPos += 3;
const unsigned int nAttrs =
attributeList->getLength();
- for(unsigned int j = 0; j < nAttrs; j++)
+ if (nAttrs != 0)
{
- XalanNode* const theNode =
attributeList->item(j);
- assert(theNode != 0 && theNode->getNodeType()
== XalanNode::ATTRIBUTE_NODE);
-
- const XPath::eMatchScore score =
nodeTest(xpath,
-
executionContext,
-
theNode,
-
XalanNode::ATTRIBUTE_NODE,
-
opPos,
-
argLen,
-
stepType);
+ const NodeTester theTester(
+ xpath,
+
executionContext,
+ opPos,
+ argLen,
+ stepType);
- if(XPath::eMatchScoreNone != score)
+ for(unsigned int j = 0; j < nAttrs; j++)
{
- subQueryResults.addNode(theNode);
+ XalanNode* const theNode =
attributeList->item(j);
+ assert(theNode != 0 &&
theNode->getNodeType() == XalanNode::ATTRIBUTE_NODE);
+
+ const XPath::eMatchScore score =
+ theTester(*theNode,
XalanNode::ATTRIBUTE_NODE);
+ assert(score == nodeTest(xpath,
executionContext, theNode, XalanNode::ATTRIBUTE_NODE, opPos, argLen, stepType));
+
+ if(XPath::eMatchScoreNone != score)
+ {
+
subQueryResults.addNode(theNode);
+ }
}
}
}
@@ -937,6 +985,10 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
+ assert(context != 0);
+
+ XalanNode* child = context->getFirstChild();
+
const XPathExpression& currentExpression =
xpath.getExpression();
@@ -944,30 +996,34 @@
// XPathExpression interface?
const int argLen =
currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
-
- opPos += 3;
-
- XalanNode* child = context->getFirstChild();
- while(0 != child)
+ if (child != 0)
{
- const XPath::eMatchScore score = nodeTest(xpath,
-
executionContext,
-
child,
-
child->getNodeType(),
-
opPos,
-
argLen,
-
stepType);
+ opPos += 3;
- if(XPath::eMatchScoreNone != score)
+ const NodeTester theTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+ stepType);
+
+ do
{
- subQueryResults.addNode(child);
- }
+ const XPath::eMatchScore score =
+ theTester(*child, child->getNodeType());
+ assert(score == nodeTest(xpath,
executionContext, child, child->getNodeType(), opPos, argLen, stepType));
- child = child->getNextSibling();
- }
+ if(XPath::eMatchScoreNone != score)
+ {
+ subQueryResults.addNode(child);
+ }
- subQueryResults.setDocumentOrder();
+ child = child->getNextSibling();
+ } while(0 != child);
+
+ subQueryResults.setDocumentOrder();
+ }
return argLen + 3;
}
@@ -983,6 +1039,8 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
+ assert(context != 0);
+
const XPathExpression& currentExpression =
xpath.getExpression();
@@ -991,24 +1049,28 @@
const int argLen =
currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
- opPos += 3;
-
// Perform a pre-order traversal of descendents...
XalanNode* pos = context;
- while(0 != pos)
- {
- if(stepType == XPathExpression::eFROM_DESCENDANTS_OR_SELF ||
- context != pos)
- {
- if(XPath::eMatchScoreNone != nodeTest(
+ opPos += 3;
+
+ const NodeTester theTester(
xpath,
executionContext,
- pos,
- pos->getNodeType(),
opPos,
argLen,
- stepType))
+ stepType);
+
+ do
+ {
+ if(stepType == XPathExpression::eFROM_DESCENDANTS_OR_SELF ||
+ context != pos)
+ {
+ const XPath::eMatchScore score =
+ theTester(*pos, pos->getNodeType());
+ assert(score == nodeTest(xpath,
executionContext, pos, pos->getNodeType(), opPos, argLen, stepType));
+
+ if(score != XPath::eMatchScoreNone)
{
subQueryResults.addNode(pos);
}
@@ -1036,7 +1098,7 @@
}
pos = nextNode;
- }
+ } while(0 != pos);
subQueryResults.setDocumentOrder();
@@ -1054,6 +1116,8 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
+ assert(context != 0);
+
const XPathExpression& currentExpression =
xpath.getExpression();
@@ -1069,19 +1133,22 @@
XalanNode* pos = context;
+ const NodeTester theTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+ stepType);
+
while(0 != pos)
{
XalanNode* nextNode = 0;
if(pos != context)
{
- const XPath::eMatchScore score = nodeTest(xpath,
-
executionContext,
-
pos,
-
pos->getNodeType(),
-
opPos,
-
argLen,
-
stepType);
+ const XPath::eMatchScore score =
+ theTester(*pos, pos->getNodeType());
+ assert(score == nodeTest(xpath,
executionContext, pos, pos->getNodeType(), opPos, argLen, stepType));
if(XPath::eMatchScoreNone != score)
{
@@ -1147,6 +1214,8 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
+ assert(context != 0);
+
const XPathExpression& currentExpression =
xpath.getExpression();
@@ -1155,30 +1224,36 @@
const int argLen =
currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
- opPos += 3;
-
XalanNode* pos = context->getNextSibling();
- while(0 != pos)
+ if (pos != 0)
{
- const XPath::eMatchScore score = nodeTest(xpath,
-
executionContext,
-
pos,
-
pos->getNodeType(),
-
opPos,
-
argLen,
-
stepType);
+ opPos += 3;
- if(XPath::eMatchScoreNone != score)
+ const NodeTester theTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+ stepType);
+
+ do
{
- subQueryResults.addNode(pos);
- }
+ const XPath::eMatchScore score =
+ theTester(*pos, pos->getNodeType());
+ assert(score == nodeTest(xpath,
executionContext, pos, pos->getNodeType(), opPos, argLen, stepType));
- pos = pos->getNextSibling();
- }
+ if(XPath::eMatchScoreNone != score)
+ {
+ subQueryResults.addNode(pos);
+ }
- subQueryResults.setDocumentOrder();
+ pos = pos->getNextSibling();
+ } while(0 != pos);
+ subQueryResults.setDocumentOrder();
+ }
+
return argLen + 3;
}
@@ -1193,6 +1268,8 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
+ assert(context != 0);
+
const XPathExpression& currentExpression =
xpath.getExpression();
@@ -1217,6 +1294,13 @@
const XalanNode* const theAttributeContextParent =
contextIsAttribute == true ?
DOMServices::getParentOfNode(*context) : 0;
+ const NodeTester theTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+ stepType);
+
while(0 != pos)
{
if(context == pos)
@@ -1224,13 +1308,9 @@
break;
}
- const double score = nodeTest(xpath,
-
executionContext,
-
pos,
-
pos->getNodeType(),
-
opPos,
-
argLen,
-
stepType);
+ const XPath::eMatchScore score =
+ theTester(*pos, pos->getNodeType());
+ assert(score == nodeTest(xpath,
executionContext, pos, pos->getNodeType(), opPos, argLen, stepType));
if(XPath::eMatchScoreNone != score)
{
@@ -1311,6 +1391,8 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
+ assert(context != 0);
+
const XPathExpression& currentExpression =
xpath.getExpression();
@@ -1319,30 +1401,36 @@
const int argLen =
currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
- opPos += 3;
-
XalanNode* pos = context->getPreviousSibling();
- while(0 != pos)
+ if (pos != 0)
{
- const double score = nodeTest(xpath,
-
executionContext,
-
pos,
-
pos->getNodeType(),
-
opPos,
-
argLen,
-
stepType);
+ opPos += 3;
- if(XPath::eMatchScoreNone != score)
+ const NodeTester theTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+ stepType);
+
+ do
{
- subQueryResults.addNode(pos);
- }
+ const XPath::eMatchScore score =
+ theTester(*pos, pos->getNodeType());
+ assert(score == nodeTest(xpath,
executionContext, pos, pos->getNodeType(), opPos, argLen, stepType));
- pos = pos->getPreviousSibling();
- }
+ if(XPath::eMatchScoreNone != score)
+ {
+ subQueryResults.addNode(pos);
+ }
- subQueryResults.setReverseDocumentOrder();
+ pos = pos->getPreviousSibling();
+ } while(0 != pos);
+ subQueryResults.setReverseDocumentOrder();
+ }
+
return argLen + 3;
}
@@ -1357,6 +1445,8 @@
int stepType,
MutableNodeRefList& subQueryResults)
{
+ assert(context != 0);
+
const XPathExpression& currentExpression =
xpath.getExpression();
@@ -1365,10 +1455,10 @@
const int argLen =
currentExpression.getOpCodeMapValue(opPos +
XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
- opPos += 3;
-
- if(context != 0 && context->getNodeType() == XalanNode::ELEMENT_NODE)
+ 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();
@@ -1376,6 +1466,13 @@
const XalanNode* theCurrentNode = context;
+ const NodeTester theTester(
+ xpath,
+ executionContext,
+ opPos,
+ argLen,
+ stepType);
+
do
{
const XalanNamedNodeMap* const attributeList =
@@ -1397,13 +1494,11 @@
if (startsWith(theNodeName,
DOMServices::s_XMLNamespaceWithSeparator) == true ||
equals(theNodeName,
DOMServices::s_XMLNamespace) == true)
{
- if(nodeTest(xpath,
-
executionContext,
- attr,
-
XalanNode::ATTRIBUTE_NODE,
- opPos,
- argLen,
-
stepType) != XPath::eMatchScoreNone)
+ const XPath::eMatchScore
score =
+ theTester(*attr,
XalanNode::ATTRIBUTE_NODE);
+ assert(score ==
nodeTest(xpath, executionContext, attr, XalanNode::ATTRIBUTE_NODE, opPos,
argLen, stepType));
+
+ if(score !=
XPath::eMatchScoreNone)
{
subQueryResults.addNode(attr);
}
@@ -1484,14 +1579,14 @@
case XPathExpression::eNODETYPE_PI:
if(XalanNode::PROCESSING_INSTRUCTION_NODE == nodeType)
{
- opPos++;
-
if(argLen == 1)
{
score = XPath::eMatchScoreNodeTest;
}
else if(argLen == 2)
{
+ opPos++;
+
const int
tokenPosition =
currentExpression.getOpCodeMapValue(opPos);
@@ -1778,4 +1873,562 @@
}
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();
+ }
+}
+
+
+
+SimpleNodeLocator::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!"));
+ }
+ 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
+SimpleNodeLocator::NodeTester::testComment(
+ const XalanNode& /* context */,
+ XalanNode::NodeType nodeType) const
+{
+ if (XalanNode::COMMENT_NODE == nodeType)
+ {
+ return XPath::eMatchScoreNodeTest;
+ }
+ else
+ {
+ return XPath::eMatchScoreNone;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::NodeTester::testText(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const
+{
+ if ((XalanNode::CDATA_SECTION_NODE == nodeType ||
+ XalanNode::TEXT_NODE == nodeType) &&
+ m_executionContext.shouldStripSourceNode(context) ==
false)
+ {
+ return XPath::eMatchScoreNodeTest;
+ }
+ else
+ {
+ return XPath::eMatchScoreNone;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::NodeTester::testPI(
+ const XalanNode& /* context */,
+ XalanNode::NodeType nodeType) const
+{
+ if (XalanNode::PROCESSING_INSTRUCTION_NODE == nodeType)
+ {
+ return XPath::eMatchScoreNodeTest;
+ }
+ else
+ {
+ return XPath::eMatchScoreNone;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::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 XPath::eMatchScoreQName;
+ }
+ else
+ {
+ return XPath::eMatchScoreNone;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::NodeTester::testNode(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const
+{
+ if (nodeType != XalanNode::CDATA_SECTION_NODE &&
+ nodeType != XalanNode::TEXT_NODE)
+ {
+ return XPath::eMatchScoreNodeTest;
+ }
+ else if (shouldStripSourceNode(context) == false)
+ {
+ return XPath::eMatchScoreNodeTest;
+ }
+ else
+ {
+ return XPath::eMatchScoreNone;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::NodeTester::testRoot(
+ const XalanNode& /* context */,
+ XalanNode::NodeType nodeType) const
+{
+ if (XalanNode::DOCUMENT_FRAGMENT_NODE == nodeType ||
+ XalanNode::DOCUMENT_NODE == nodeType)
+ {
+ return XPath::eMatchScoreOther;
+ }
+ else
+ {
+ return XPath::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
+SimpleNodeLocator::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 XPath::eMatchScoreNone;
+ }
+ else
+ {
+ return XPath::eMatchScoreQName;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::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 XPath::eMatchScoreNone;
+ }
+ else
+ {
+ return XPath::eMatchScoreQName;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::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 XPath::eMatchScoreNone;
+ }
+ else
+ {
+ return XPath::eMatchScoreNodeTest;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::NodeTester::testAttributeTotallyWild(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const
+{
+ if (XalanNode::ATTRIBUTE_NODE != nodeType ||
+ isNamespaceDeclaration(context) == true)
+ {
+ return XPath::eMatchScoreNone;
+ }
+ else
+ {
+ return XPath::eMatchScoreNodeTest;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::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 XPath::eMatchScoreNone;
+ }
+ else
+ {
+ return XPath::eMatchScoreQName;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::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 XPath::eMatchScoreNone;
+ }
+ else
+ {
+ return XPath::eMatchScoreQName;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::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 XPath::eMatchScoreNone;
+ }
+ else
+ {
+ return XPath::eMatchScoreNSWild;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::NodeTester::testElementTotallyWild(
+ const XalanNode& /* context */,
+ XalanNode::NodeType nodeType) const
+{
+ assert(m_targetNamespace == 0 && m_targetLocalName == 0);
+
+ if (XalanNode::ELEMENT_NODE != nodeType)
+ {
+ return XPath::eMatchScoreNone;
+ }
+ else
+ {
+ return XPath::eMatchScoreNodeTest;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::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 XPath::eMatchScoreNone;
+ }
+ else
+ {
+ return XPath::eMatchScoreQName;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::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 XPath::eMatchScoreNone;
+ }
+ else
+ {
+ return XPath::eMatchScoreNodeTest;
+ }
+}
+
+
+
+XPath::eMatchScore
+SimpleNodeLocator::NodeTester::testDefault(
+ const XalanNode& /* context */,
+ XalanNode::NodeType /* nodeType */) const
+{
+ return XPath::eMatchScoreNone;
+}
+
+
+
+bool
+SimpleNodeLocator::NodeTester::matchLocalName(const XalanNode&
context) const
+{
+ assert(m_targetLocalName != 0);
+
+ return length(context.getNamespaceURI()) == 0 &&
+ equals(DOMServices::getLocalNameOfNode(context),
*m_targetLocalName);
+}
+
+
+
+bool
+SimpleNodeLocator::NodeTester::matchNamespaceURI(const XalanNode&
context) const
+{
+ assert(m_targetNamespace != 0);
+
+ return equals(context.getNamespaceURI(), *m_targetNamespace);
+}
+
+
+
+bool
+SimpleNodeLocator::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
+SimpleNodeLocator::NodeTester::matchNamespace(const XalanNode&
context) const
+{
+ assert(m_targetLocalName != 0);
+
+ return equals(context.getNodeValue(), *m_targetLocalName);
+}
+
+
+
+bool
+SimpleNodeLocator::NodeTester::shouldStripSourceNode(const XalanNode&
context) const
+{
+ assert(context.getNodeType() == XalanNode::CDATA_SECTION_NODE ||
+ context.getNodeType() == XalanNode::TEXT_NODE);
+
+ return m_executionContext.shouldStripSourceNode(context);
}
1.16 +136 -0 xml-xalan/c/src/XPath/SimpleNodeLocator.hpp
Index: SimpleNodeLocator.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/SimpleNodeLocator.hpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- SimpleNodeLocator.hpp 2001/07/08 18:40:08 1.15
+++ SimpleNodeLocator.hpp 2001/08/06 01:39:29 1.16
@@ -101,6 +101,142 @@
XalanNode& context,
int opPos);
+ class NodeTester
+ {
+ public:
+
+ NodeTester(
+ const XPath& xpath,
+ XPathExecutionContext& executionContext,
+ int opPos,
+ int argLen,
+ int stepType);
+
+ XPath::eMatchScore
+ operator()(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const
+ {
+ assert(context.getNodeType() == nodeType);
+
+ return (this->*m_testFunction)(context, nodeType);
+ }
+
+ private:
+
+ typedef XPath::eMatchScore
(NodeTester::*MemberFunctionPtr)(const XalanNode&, XalanNode::NodeType) const;
+
+
+ XPath::eMatchScore
+ testComment(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testText(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testPI(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testPIName(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testNode(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testRoot(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testAttributeNCName(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testAttributeQName(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testAttributeNamespaceOnly(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testAttributeTotallyWild(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testElementNCName(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testElementQName(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testElementNamespaceOnly(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testElementTotallyWild(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testNamespaceNCName(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::eMatchScore
+ testNamespaceTotallyWild(
+ const XalanNode& context,
+ XalanNode::NodeType nodeType) const;
+
+ XPath::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:
static void
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]