GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: XercesXPath.cpp 903997 2010-01-28 08:28:06Z borisk $ 00020 */ 00021 00022 // --------------------------------------------------------------------------- 00023 // Includes 00024 // --------------------------------------------------------------------------- 00025 #include <xercesc/validators/schema/identity/XercesXPath.hpp> 00026 #include <xercesc/validators/schema/identity/XPathSymbols.hpp> 00027 #include <xercesc/validators/schema/identity/XPathException.hpp> 00028 #include <xercesc/validators/schema/NamespaceScope.hpp> 00029 #include <xercesc/util/StringPool.hpp> 00030 #include <xercesc/util/Janitor.hpp> 00031 #include <xercesc/framework/XMLBuffer.hpp> 00032 #include <xercesc/internal/XMLReader.hpp> 00033 #include <xercesc/util/RuntimeException.hpp> 00034 #include <xercesc/util/OutOfMemoryException.hpp> 00035 00036 #include <xercesc/internal/XTemplateSerializer.hpp> 00037 00038 XERCES_CPP_NAMESPACE_BEGIN 00039 00040 00041 // --------------------------------------------------------------------------- 00042 // Static data 00043 // --------------------------------------------------------------------------- 00044 const XMLByte XPathScanner::fASCIICharMap[128] = 00045 { 00046 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 2, 0, 0, 00047 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00048 2, 3, 4, 1, 5, 1, 1, 4, 6, 7, 8, 9, 10, 11, 12, 13, 00049 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 1, 16, 17, 18, 1, 00050 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 00051 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 1, 22, 1, 23, 00052 1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 00053 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 1, 24, 1, 1, 1 00054 }; 00055 00056 00057 // --------------------------------------------------------------------------- 00058 // XercesNodeTest: Constructors and Destructor 00059 // --------------------------------------------------------------------------- 00060 XercesNodeTest::XercesNodeTest(const short aType, 00061 MemoryManager* const manager) 00062 : fType(aType) 00063 , fName(new (manager) QName(manager)) 00064 { 00065 } 00066 00067 XercesNodeTest::XercesNodeTest(const QName* const qName) 00068 : fType(NodeType_QNAME) 00069 , fName(new (qName->getMemoryManager()) QName(*qName)) 00070 { 00071 } 00072 00073 XercesNodeTest::XercesNodeTest(const XMLCh* const prefix, 00074 const unsigned int uriId, 00075 MemoryManager* const manager) 00076 : fType(NodeType_NAMESPACE) 00077 , fName(new (manager) QName(manager)) 00078 { 00079 fName->setURI(uriId); 00080 fName->setPrefix(prefix); 00081 } 00082 00083 XercesNodeTest::XercesNodeTest(const XercesNodeTest& other) 00084 : XSerializable(other) 00085 , XMemory(other) 00086 , fType(other.fType) 00087 , fName(new ((other.fName)->getMemoryManager()) QName(*other.fName)) 00088 { 00089 } 00090 00091 /*** 00092 * Support for Serialization/De-serialization 00093 ***/ 00094 00095 IMPL_XSERIALIZABLE_TOCREATE(XercesNodeTest) 00096 00097 void XercesNodeTest::serialize(XSerializeEngine& serEng) 00098 { 00099 00100 if (serEng.isStoring()) 00101 { 00102 serEng<<fType; 00103 serEng<<fName; 00104 } 00105 else 00106 { 00107 serEng>>fType; 00108 serEng>>fName; 00109 } 00110 } 00111 00112 XercesNodeTest::XercesNodeTest(MemoryManager* const) 00113 :fType(NodeType_UNKNOWN) 00114 ,fName(0) 00115 { 00116 } 00117 00118 // --------------------------------------------------------------------------- 00119 // XercesNodeTest: Operators 00120 // --------------------------------------------------------------------------- 00121 XercesNodeTest& XercesNodeTest::operator=(const XercesNodeTest& other) 00122 { 00123 if (this == &other) 00124 return *this; 00125 00126 fType = other.fType; 00127 fName->setValues(*(other.fName)); 00128 return *this; 00129 } 00130 00131 bool XercesNodeTest::operator ==(const XercesNodeTest& other) const { 00132 00133 if (this == &other) 00134 return true; 00135 00136 if (fType != other.fType) 00137 return false; 00138 00139 return (*fName == *(other.fName)); 00140 } 00141 00142 00143 bool XercesNodeTest::operator !=(const XercesNodeTest& other) const { 00144 00145 return !operator==(other); 00146 } 00147 00148 // --------------------------------------------------------------------------- 00149 // XercesStep: Constructors and Destructor 00150 // --------------------------------------------------------------------------- 00151 XercesStep::XercesStep(const unsigned short axisType, XercesNodeTest* const nodeTest) 00152 : fAxisType(axisType) 00153 , fNodeTest(nodeTest) 00154 { 00155 } 00156 00157 XercesStep::XercesStep(const XercesStep& other) 00158 : XSerializable(other) 00159 , XMemory(other) 00160 , fAxisType(other.fAxisType) 00161 , fNodeTest(0) 00162 { 00163 fNodeTest = new (other.fNodeTest->getName()->getMemoryManager()) XercesNodeTest(*(other.fNodeTest)); 00164 } 00165 00166 00167 // --------------------------------------------------------------------------- 00168 // XercesStep: Operators 00169 // --------------------------------------------------------------------------- 00170 XercesStep& XercesStep::operator=(const XercesStep& other) 00171 { 00172 if (this == &other) 00173 return *this; 00174 00175 fAxisType = other.fAxisType; 00176 *fNodeTest = *(other.fNodeTest); 00177 return *this; 00178 } 00179 00180 bool XercesStep::operator==(const XercesStep& other) const { 00181 00182 if (this == &other) 00183 return true; 00184 00185 if (fAxisType != other.fAxisType) 00186 return false; 00187 00188 if (fAxisType == XercesStep::AxisType_CHILD || 00189 fAxisType == XercesStep::AxisType_ATTRIBUTE) { 00190 return (*fNodeTest == *(other.fNodeTest)); 00191 } 00192 00193 return true; 00194 } 00195 00196 bool XercesStep::operator!=(const XercesStep& other) const { 00197 00198 return !operator==(other); 00199 } 00200 00201 /*** 00202 * Support for Serialization/De-serialization 00203 ***/ 00204 00205 IMPL_XSERIALIZABLE_TOCREATE(XercesStep) 00206 00207 void XercesStep::serialize(XSerializeEngine& serEng) 00208 { 00209 if (serEng.isStoring()) 00210 { 00211 serEng<<(int)fAxisType; 00212 serEng<<fNodeTest; 00213 } 00214 else 00215 { 00216 int i; 00217 serEng>>i; 00218 fAxisType = (unsigned short) i; 00219 00220 serEng>>fNodeTest; 00221 } 00222 } 00223 00224 XercesStep::XercesStep(MemoryManager* const) 00225 :fAxisType(AxisType_UNKNOWN) 00226 ,fNodeTest(0) 00227 { 00228 } 00229 00230 // --------------------------------------------------------------------------- 00231 // XercesLocationPath: Constructors and Destructor 00232 // --------------------------------------------------------------------------- 00233 XercesLocationPath::XercesLocationPath(RefVectorOf<XercesStep>* const steps) 00234 : fSteps(steps) 00235 { 00236 } 00237 00238 // --------------------------------------------------------------------------- 00239 // XercesLocationPath: Operators 00240 // --------------------------------------------------------------------------- 00241 bool XercesLocationPath::operator==(const XercesLocationPath& other) const { 00242 00243 XMLSize_t stepsSize = fSteps->size(); 00244 00245 if (stepsSize != other.fSteps->size()) 00246 return false; 00247 00248 for (XMLSize_t i=0; i < stepsSize; i++) { 00249 if (*(fSteps->elementAt(i)) != *(other.fSteps->elementAt(i))) 00250 return false; 00251 } 00252 00253 return true; 00254 } 00255 00256 bool XercesLocationPath::operator!=(const XercesLocationPath& other) const { 00257 00258 return !operator==(other); 00259 } 00260 00261 /*** 00262 * Support for Serialization/De-serialization 00263 ***/ 00264 00265 IMPL_XSERIALIZABLE_TOCREATE(XercesLocationPath) 00266 00267 void XercesLocationPath::serialize(XSerializeEngine& serEng) 00268 { 00269 if (serEng.isStoring()) 00270 { 00271 /*** 00272 * Serialize RefVectorOf<XercesStep>* fSteps; 00273 ***/ 00274 XTemplateSerializer::storeObject(fSteps, serEng); 00275 } 00276 else 00277 { 00278 /*** 00279 * Deserialize RefVectorOf<XercesStep>* fSteps; 00280 ***/ 00281 XTemplateSerializer::loadObject(&fSteps, 8, true, serEng); 00282 } 00283 } 00284 00285 XercesLocationPath::XercesLocationPath(MemoryManager* const) 00286 :fSteps(0) 00287 { 00288 } 00289 00290 typedef JanitorMemFunCall<XercesXPath> CleanupType; 00291 00292 // --------------------------------------------------------------------------- 00293 // XercesPath: Constructors and Destructor 00294 // --------------------------------------------------------------------------- 00295 XercesXPath::XercesXPath(const XMLCh* const xpathExpr, 00296 XMLStringPool* const stringPool, 00297 XercesNamespaceResolver* const scopeContext, 00298 const unsigned int emptyNamespaceId, 00299 const bool isSelector, 00300 MemoryManager* const manager) 00301 : fEmptyNamespaceId(emptyNamespaceId) 00302 , fExpression(0) 00303 , fLocationPaths(0) 00304 , fMemoryManager(manager) 00305 { 00306 CleanupType cleanup(this, &XercesXPath::cleanUp); 00307 00308 try 00309 { 00310 fExpression = XMLString::replicate(xpathExpr, fMemoryManager); 00311 parseExpression(stringPool, scopeContext); 00312 00313 if (isSelector) { 00314 checkForSelectedAttributes(); 00315 } 00316 } 00317 catch(const OutOfMemoryException&) 00318 { 00319 cleanup.release(); 00320 00321 throw; 00322 } 00323 00324 cleanup.release(); 00325 } 00326 00327 XercesXPath::~XercesXPath() { 00328 cleanUp(); 00329 } 00330 00331 00332 // --------------------------------------------------------------------------- 00333 // XercesXPath: Operators 00334 // --------------------------------------------------------------------------- 00335 bool XercesXPath::operator==(const XercesXPath& other) const { 00336 00337 XMLSize_t locPathSize = fLocationPaths->size(); 00338 00339 if (locPathSize != other.fLocationPaths->size()) 00340 return false; 00341 00342 for (XMLSize_t i=0; i < locPathSize; i++) { 00343 if (*(fLocationPaths->elementAt(i)) != *(other.fLocationPaths->elementAt(i))) 00344 return false; 00345 } 00346 00347 return true; 00348 } 00349 00350 bool XercesXPath::operator!=(const XercesXPath& other) const { 00351 00352 return !operator==(other); 00353 } 00354 00355 // --------------------------------------------------------------------------- 00356 // XercesPath: Helper methods 00357 // --------------------------------------------------------------------------- 00358 void XercesXPath::cleanUp() { 00359 00360 fMemoryManager->deallocate(fExpression);//delete [] fExpression; 00361 delete fLocationPaths; 00362 } 00363 00364 void XercesXPath::checkForSelectedAttributes() { 00365 00366 // verify that an attribute is not selected 00367 XMLSize_t locSize = (fLocationPaths) ? fLocationPaths->size() : 0; 00368 00369 for (XMLSize_t i = 0; i < locSize; i++) { 00370 00371 XercesLocationPath* locPath = fLocationPaths->elementAt(i); 00372 XMLSize_t stepSize = locPath->getStepSize(); 00373 00374 if (stepSize) { 00375 if (locPath->getStep(stepSize - 1)->getAxisType() == XercesStep::AxisType_ATTRIBUTE) { 00376 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoAttrSelector, fMemoryManager); 00377 } 00378 } 00379 } 00380 } 00381 00382 void XercesXPath::parseExpression(XMLStringPool* const stringPool, 00383 XercesNamespaceResolver* const scopeContext) { 00384 00385 XMLSize_t length = XMLString::stringLen(fExpression); 00386 00387 if (!length) { 00388 return; 00389 } 00390 00391 ValueVectorOf<int> tokens(16, fMemoryManager); 00392 XPathScannerForSchema scanner(stringPool); 00393 if(!scanner.scanExpression(fExpression, 0, length, &tokens)) 00394 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_TokenNotSupported, fMemoryManager); 00395 00396 bool firstTokenOfLocationPath=true; 00397 XMLSize_t tokenCount = tokens.size(); 00398 RefVectorOf<XercesStep>* stepsVector = new (fMemoryManager) RefVectorOf<XercesStep>(16, true, fMemoryManager); 00399 Janitor<RefVectorOf<XercesStep> > janSteps(stepsVector); 00400 00401 if (tokenCount) { 00402 fLocationPaths = new (fMemoryManager) RefVectorOf<XercesLocationPath>(8, true, fMemoryManager); 00403 } 00404 00405 for (XMLSize_t i = 0; i < tokenCount; i++) { 00406 00407 int aToken = tokens.elementAt(i); 00408 bool isNamespace=false; 00409 00410 switch (aToken) { 00411 case XercesXPath::EXPRTOKEN_OPERATOR_UNION: 00412 { 00413 if (i == 0) { 00414 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoUnionAtStart, fMemoryManager); 00415 } 00416 00417 XMLSize_t stepsSize = stepsVector->size(); 00418 00419 if (stepsSize == 0) { 00420 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoMultipleUnion, fMemoryManager); 00421 } 00422 00423 if(stepsVector->elementAt(0)->getAxisType()!=XercesStep::AxisType_SELF) 00424 { 00425 // prepend ./ 00426 XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_NODE, fMemoryManager); 00427 XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_SELF, nodeTest); 00428 stepsVector->insertElementAt(step, 0); 00429 } 00430 XercesLocationPath* newPath = new (fMemoryManager) XercesLocationPath(stepsVector); 00431 janSteps.orphan(); 00432 bool bFound=false; 00433 for(XMLSize_t i=0;i<fLocationPaths->size();i++) 00434 if((*(fLocationPaths->elementAt(i)))==(*newPath)) 00435 { 00436 bFound=true; 00437 break; 00438 } 00439 if(bFound) 00440 delete newPath; 00441 else 00442 fLocationPaths->addElement(newPath); 00443 stepsVector = new (fMemoryManager) RefVectorOf<XercesStep>(16, true, fMemoryManager); 00444 janSteps.reset(stepsVector); 00445 firstTokenOfLocationPath = true; 00446 } 00447 break; 00448 case XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE: 00449 { 00450 // consume "::" token and drop through 00451 i++; 00452 } 00453 case XercesXPath::EXPRTOKEN_ATSIGN: 00454 { 00455 // consume QName token 00456 if (i == tokenCount - 1) { 00457 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_MissingAttr, fMemoryManager); 00458 } 00459 00460 aToken = tokens.elementAt(++i); 00461 00462 if (aToken != XercesXPath::EXPRTOKEN_NAMETEST_QNAME 00463 && aToken!= XercesXPath::EXPRTOKEN_NAMETEST_ANY 00464 && aToken!= XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE) { 00465 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedToken1, fMemoryManager); 00466 } 00467 00468 bool isNamespaceAtt=false; 00469 00470 switch (aToken) { 00471 00472 case XercesXPath::EXPRTOKEN_NAMETEST_ANY: 00473 { 00474 XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_WILDCARD, fMemoryManager); 00475 XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_ATTRIBUTE, nodeTest); 00476 stepsVector->addElement(step); 00477 break; 00478 } 00479 case XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE: 00480 { 00481 isNamespaceAtt = true; 00482 } 00483 case XercesXPath::EXPRTOKEN_NAMETEST_QNAME: 00484 { 00485 aToken = tokens.elementAt(++i); 00486 00487 const XMLCh* prefix = XMLUni::fgZeroLenString; 00488 unsigned int uri = fEmptyNamespaceId; 00489 00490 if (scopeContext && aToken != -1) { 00491 00492 prefix = stringPool->getValueForId(aToken); 00493 uri = scopeContext->getNamespaceForPrefix(prefix); 00494 } 00495 00496 if (aToken != -1 && scopeContext && uri == fEmptyNamespaceId) { 00497 ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_PrefixNoURI, prefix, fMemoryManager); 00498 } 00499 00500 if (isNamespaceAtt) { 00501 00502 // build step 00503 XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(prefix, uri, fMemoryManager); 00504 XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_ATTRIBUTE, nodeTest); 00505 stepsVector->addElement(step); 00506 break; 00507 } 00508 00509 aToken = tokens.elementAt(++i); 00510 00511 const XMLCh* localPart = stringPool->getValueForId(aToken); 00512 QName aQName(prefix, localPart, uri, fMemoryManager); 00513 00514 // build step 00515 XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(&aQName); 00516 XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_ATTRIBUTE, nodeTest); 00517 stepsVector->addElement(step); 00518 break; 00519 } 00520 } 00521 00522 firstTokenOfLocationPath=false; 00523 break; 00524 } 00525 case XercesXPath::EXPRTOKEN_DOUBLE_COLON: 00526 { 00527 // should never have a bare double colon 00528 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoDoubleColon, fMemoryManager); 00529 } 00530 case XercesXPath::EXPRTOKEN_AXISNAME_CHILD: 00531 { 00532 // consume "::" token and drop through 00533 i++; 00534 00535 if (i == tokenCount - 1) { 00536 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep1, fMemoryManager); 00537 } 00538 00539 firstTokenOfLocationPath=false; 00540 break; 00541 } 00542 case XercesXPath::EXPRTOKEN_NAMETEST_ANY: 00543 { 00544 XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_WILDCARD, fMemoryManager); 00545 XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_CHILD, nodeTest); 00546 stepsVector->addElement(step); 00547 firstTokenOfLocationPath = false; 00548 break; 00549 } 00550 case XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE: 00551 { 00552 isNamespace=true; 00553 } 00554 case XercesXPath::EXPRTOKEN_NAMETEST_QNAME: 00555 { 00556 // consume QName token 00557 aToken = tokens.elementAt(++i); 00558 00559 const XMLCh* prefix = XMLUni::fgZeroLenString; 00560 unsigned int uri = fEmptyNamespaceId; 00561 00562 if (scopeContext && aToken != -1) { 00563 00564 prefix = stringPool->getValueForId(aToken); 00565 uri = scopeContext->getNamespaceForPrefix(prefix); 00566 } 00567 00568 if (aToken != -1 && scopeContext && uri == fEmptyNamespaceId) { 00569 ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_PrefixNoURI, prefix, fMemoryManager); 00570 } 00571 00572 if (isNamespace) { 00573 00574 // build step 00575 XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(prefix, uri, fMemoryManager); 00576 XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_CHILD, nodeTest); 00577 stepsVector->addElement(step); 00578 break; 00579 } 00580 00581 aToken = tokens.elementAt(++i); 00582 const XMLCh* localPart = stringPool->getValueForId(aToken); 00583 QName aQName(prefix, localPart, uri, fMemoryManager); 00584 00585 // build step 00586 XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(&aQName); 00587 XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_CHILD, nodeTest); 00588 stepsVector->addElement(step); 00589 firstTokenOfLocationPath = false; 00590 break; 00591 } 00592 case XercesXPath::EXPRTOKEN_PERIOD: 00593 { 00594 // build step 00595 XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_NODE, fMemoryManager); 00596 XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_SELF, nodeTest); 00597 stepsVector->addElement(step); 00598 00599 if (firstTokenOfLocationPath && i+1 < tokenCount) { 00600 00601 aToken = tokens.elementAt(i+1); 00602 00603 if (aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH){ 00604 00605 if (++i == tokenCount - 1) { 00606 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep2, fMemoryManager); 00607 } 00608 00609 if (i+1 < tokenCount) { 00610 00611 aToken = tokens.elementAt(i+1); 00612 00613 if (aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH) { 00614 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoForwardSlash, fMemoryManager); 00615 } 00616 } 00617 // build step 00618 nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_NODE, fMemoryManager); 00619 step = new (fMemoryManager) XercesStep(XercesStep::AxisType_DESCENDANT, nodeTest); 00620 stepsVector->addElement(step); 00621 } 00622 } 00623 firstTokenOfLocationPath=false; 00624 break; 00625 } 00626 case XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH: 00627 { 00628 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoDoubleForwardSlash, fMemoryManager); 00629 } 00630 case XercesXPath::EXPRTOKEN_OPERATOR_SLASH: 00631 { 00632 if (i == 0) { 00633 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoForwardSlashAtStart, fMemoryManager); 00634 } 00635 00636 // keep on truckin' 00637 if (firstTokenOfLocationPath) { 00638 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoSelectionOfRoot, fMemoryManager); 00639 } 00640 00641 if (i == tokenCount - 1) { 00642 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep3, fMemoryManager); 00643 } 00644 00645 aToken = tokens.elementAt(i+1); 00646 if(aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH || aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH || aToken == XercesXPath::EXPRTOKEN_OPERATOR_UNION) 00647 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep3, fMemoryManager); 00648 00649 firstTokenOfLocationPath=false; 00650 break; 00651 } 00652 default: 00653 firstTokenOfLocationPath=false; 00654 } 00655 } 00656 00657 XMLSize_t stepsSize = stepsVector->size(); 00658 00659 if (stepsSize == 0) { 00660 if (!fLocationPaths || fLocationPaths->size() == 0) { 00661 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_EmptyExpr, fMemoryManager); 00662 } 00663 else { 00664 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoUnionAtEnd, fMemoryManager); 00665 } 00666 } 00667 00668 if(stepsVector->elementAt(0)->getAxisType()!=XercesStep::AxisType_SELF) 00669 { 00670 // prepend ./ 00671 XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NodeType_NODE, fMemoryManager); 00672 XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::AxisType_SELF, nodeTest); 00673 stepsVector->insertElementAt(step, 0); 00674 } 00675 XercesLocationPath* newPath = new (fMemoryManager) XercesLocationPath(stepsVector); 00676 janSteps.orphan(); 00677 bool bFound=false; 00678 for(XMLSize_t j=0;j<fLocationPaths->size();j++) 00679 if((*(fLocationPaths->elementAt(j)))==(*newPath)) 00680 { 00681 bFound=true; 00682 break; 00683 } 00684 if(bFound) 00685 delete newPath; 00686 else 00687 fLocationPaths->addElement(newPath); 00688 } 00689 00690 /*** 00691 * Support for Serialization/De-serialization 00692 ***/ 00693 00694 IMPL_XSERIALIZABLE_TOCREATE(XercesXPath) 00695 00696 void XercesXPath::serialize(XSerializeEngine& serEng) 00697 { 00698 00699 if (serEng.isStoring()) 00700 { 00701 serEng<<fEmptyNamespaceId; 00702 serEng.writeString(fExpression); 00703 00704 /*** 00705 * Serialize RefVectorOf<XercesLocationPath>* fLocationPaths; 00706 ***/ 00707 XTemplateSerializer::storeObject(fLocationPaths, serEng); 00708 } 00709 else 00710 { 00711 serEng>>fEmptyNamespaceId; 00712 serEng.readString(fExpression); 00713 00714 /*** 00715 * Deserialize RefVectorOf<XercesLocationPath>* fLocationPaths; 00716 ***/ 00717 XTemplateSerializer::loadObject(&fLocationPaths, 8, true, serEng); 00718 } 00719 } 00720 00721 XercesXPath::XercesXPath(MemoryManager* const manager) 00722 :fEmptyNamespaceId(0) 00723 ,fExpression(0) 00724 ,fLocationPaths(0) 00725 ,fMemoryManager(manager) 00726 { 00727 } 00728 00729 // --------------------------------------------------------------------------- 00730 // XPathScanner: Constructors and Destructor 00731 // --------------------------------------------------------------------------- 00732 XPathScanner::XPathScanner(XMLStringPool* const stringPool) 00733 : fAndSymbol (0) 00734 , fOrSymbol(0) 00735 , fModSymbol(0) 00736 , fDivSymbol(0) 00737 , fCommentSymbol(0) 00738 , fTextSymbol(0) 00739 , fPISymbol(0) 00740 , fNodeSymbol(0) 00741 , fAncestorSymbol(0) 00742 , fAncestorOrSelfSymbol(0) 00743 , fAttributeSymbol(0) 00744 , fChildSymbol(0) 00745 , fDescendantSymbol(0) 00746 , fDescendantOrSelfSymbol(0) 00747 , fFollowingSymbol(0) 00748 , fFollowingSiblingSymbol(0) 00749 , fNamespaceSymbol(0) 00750 , fParentSymbol(0) 00751 , fPrecedingSymbol(0) 00752 , fPrecedingSiblingSymbol(0) 00753 , fSelfSymbol(0) 00754 , fStringPool(stringPool) 00755 { 00756 init(); 00757 } 00758 00759 // --------------------------------------------------------------------------- 00760 // XPathScanner: Helper methods 00761 // --------------------------------------------------------------------------- 00762 void XPathScanner::init() { 00763 00764 fAndSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_AND); 00765 fOrSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_OR); 00766 fModSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_MOD); 00767 fDivSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DIV); 00768 fCommentSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_COMMENT); 00769 fTextSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_TEXT); 00770 fPISymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PI); 00771 fNodeSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_NODE); 00772 fAncestorSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ANCESTOR); 00773 fAncestorOrSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ANCESTOR_OR_SELF); 00774 fAttributeSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ATTRIBUTE); 00775 fChildSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_CHILD); 00776 fDescendantSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DESCENDANT); 00777 fDescendantOrSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DESCENDANT_OR_SELF); 00778 fFollowingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_FOLLOWING); 00779 fFollowingSiblingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_FOLLOWING_SIBLING); 00780 fNamespaceSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_NAMESPACE); 00781 fParentSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PARENT); 00782 fPrecedingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PRECEDING); 00783 fPrecedingSiblingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PRECEDING_SIBLING); 00784 fSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_SELF); 00785 } 00786 00787 00788 // --------------------------------------------------------------------------- 00789 // XPathScanner: Scan methods 00790 // --------------------------------------------------------------------------- 00791 bool XPathScanner::scanExpression(const XMLCh* const data, 00792 XMLSize_t currentOffset, 00793 const XMLSize_t endOffset, 00794 ValueVectorOf<int>* const tokens) { 00795 00796 bool starIsMultiplyOperator = false; 00797 XMLSize_t nameOffset = 0; 00798 int nameHandle = -1; 00799 int prefixHandle = -1; 00800 XMLCh ch; 00801 XMLBuffer dataBuffer(128, tokens->getMemoryManager()); 00802 00803 while (currentOffset != endOffset) { 00804 00805 ch = data[currentOffset]; 00806 00807 while (XMLChar1_0::isWhitespace(ch)) { 00808 00809 if (++currentOffset == endOffset) { 00810 break; 00811 } 00812 00813 ch = data[currentOffset]; 00814 } 00815 00816 if (currentOffset == endOffset) { 00817 break; 00818 } 00819 // 00820 // [28] ExprToken ::= '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::' 00821 // | NameTest | NodeType | Operator | FunctionName 00822 // | AxisName | Literal | Number | VariableReference 00823 // 00824 XMLByte chartype = (ch >= 0x80) ? (XMLByte)CHARTYPE_NONASCII : fASCIICharMap[ch]; 00825 00826 switch (chartype) { 00827 case CHARTYPE_OPEN_PAREN: // '(' 00828 addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_PAREN); 00829 starIsMultiplyOperator = false; 00830 ++currentOffset; 00831 break; 00832 case CHARTYPE_CLOSE_PAREN: // ')' 00833 addToken(tokens, XercesXPath::EXPRTOKEN_CLOSE_PAREN); 00834 starIsMultiplyOperator = true; 00835 ++currentOffset; 00836 break; 00837 case CHARTYPE_OPEN_BRACKET: // '[' 00838 addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_BRACKET); 00839 starIsMultiplyOperator = false; 00840 ++currentOffset; 00841 break; 00842 case CHARTYPE_CLOSE_BRACKET: // ']' 00843 addToken(tokens, XercesXPath::EXPRTOKEN_CLOSE_BRACKET); 00844 starIsMultiplyOperator = true; 00845 ++currentOffset; 00846 break; 00847 // 00848 // [30] Number ::= Digits ('.' Digits?)? | '.' Digits 00849 // ^^^^^^^^^^ 00850 // 00851 case CHARTYPE_PERIOD: // '.', '..' or '.' Digits 00852 if (currentOffset + 1 == endOffset) { 00853 addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD); 00854 starIsMultiplyOperator = true; 00855 currentOffset++; 00856 break; 00857 } 00858 00859 ch = data[currentOffset + 1]; 00860 00861 if (ch == chPeriod) { // '..' 00862 addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_PERIOD); 00863 starIsMultiplyOperator = true; 00864 currentOffset += 2; 00865 } else if (ch >= chDigit_0 && ch <= chDigit_9) { 00866 addToken(tokens, XercesXPath::EXPRTOKEN_NUMBER); 00867 starIsMultiplyOperator = true; 00868 currentOffset = scanNumber(data, endOffset, currentOffset, tokens); 00869 } else if (ch == chForwardSlash) { 00870 addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD); 00871 starIsMultiplyOperator = true; 00872 currentOffset++; 00873 } else if (ch == chPipe) { // '|' 00874 addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD); 00875 starIsMultiplyOperator = true; 00876 currentOffset++; 00877 } else if (XMLChar1_0::isWhitespace(ch)) { 00878 do { 00879 if (++currentOffset == endOffset) 00880 break; 00881 00882 ch = data[currentOffset]; 00883 } while (XMLChar1_0::isWhitespace(ch)); 00884 00885 if (currentOffset == endOffset || ch == chPipe || ch == chForwardSlash) { 00886 addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD); 00887 starIsMultiplyOperator = true; 00888 break; 00889 } 00890 } else { 00891 XMLCh str[2]= {ch, 0 }; 00892 ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_InvalidChar, str, tokens->getMemoryManager()); 00893 } 00894 00895 break; 00896 case CHARTYPE_ATSIGN: // '@' 00897 addToken(tokens, XercesXPath::EXPRTOKEN_ATSIGN); 00898 starIsMultiplyOperator = false; 00899 ++currentOffset; 00900 break; 00901 case CHARTYPE_COMMA: // ',' 00902 addToken(tokens, XercesXPath::EXPRTOKEN_COMMA); 00903 starIsMultiplyOperator = false; 00904 ++currentOffset; 00905 break; 00906 case CHARTYPE_COLON: // '::' 00907 if (++currentOffset == endOffset) { 00908 return false; // REVISIT 00909 } 00910 ch = data[currentOffset]; 00911 00912 if (ch != chColon) { 00913 return false; // REVISIT 00914 } 00915 addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_COLON); 00916 starIsMultiplyOperator = false; 00917 ++currentOffset; 00918 break; 00919 case CHARTYPE_SLASH: // '/' and '//' 00920 if (++currentOffset == endOffset) { 00921 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_SLASH); 00922 starIsMultiplyOperator = false; 00923 break; 00924 } 00925 00926 ch = data[currentOffset]; 00927 00928 if (ch == chForwardSlash) { // '//' 00929 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH); 00930 starIsMultiplyOperator = false; 00931 ++currentOffset; 00932 } else { 00933 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_SLASH); 00934 starIsMultiplyOperator = false; 00935 } 00936 break; 00937 case CHARTYPE_UNION: // '|' 00938 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_UNION); 00939 starIsMultiplyOperator = false; 00940 ++currentOffset; 00941 break; 00942 case CHARTYPE_PLUS: // '+' 00943 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_PLUS); 00944 starIsMultiplyOperator = false; 00945 ++currentOffset; 00946 break; 00947 case CHARTYPE_MINUS: // '-' 00948 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MINUS); 00949 starIsMultiplyOperator = false; 00950 ++currentOffset; 00951 break; 00952 case CHARTYPE_EQUAL: // '=' 00953 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_EQUAL); 00954 starIsMultiplyOperator = false; 00955 ++currentOffset; 00956 break; 00957 case CHARTYPE_EXCLAMATION: // '!=' 00958 if (++currentOffset == endOffset) { 00959 return false; // REVISIT 00960 } 00961 00962 ch = data[currentOffset]; 00963 00964 if (ch != chEqual) { 00965 return false; // REVISIT 00966 } 00967 00968 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_NOT_EQUAL); 00969 starIsMultiplyOperator = false; 00970 ++currentOffset; 00971 break; 00972 case CHARTYPE_LESS: // '<' and '<=' 00973 if (++currentOffset == endOffset) { 00974 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS); 00975 starIsMultiplyOperator = false; 00976 break; 00977 } 00978 00979 ch = data[currentOffset]; 00980 00981 if (ch == chEqual) { // '<=' 00982 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS_EQUAL); 00983 starIsMultiplyOperator = false; 00984 ++currentOffset; 00985 } else { 00986 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS); 00987 starIsMultiplyOperator = false; 00988 } 00989 break; 00990 case CHARTYPE_GREATER: // '>' and '>=' 00991 if (++currentOffset == endOffset) { 00992 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER); 00993 starIsMultiplyOperator = false; 00994 break; 00995 } 00996 00997 ch = data[currentOffset]; 00998 00999 if (ch == chEqual) { // '>=' 01000 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER_EQUAL); 01001 starIsMultiplyOperator = false; 01002 ++currentOffset; 01003 } else { 01004 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER); 01005 starIsMultiplyOperator = false; 01006 } 01007 break; 01008 // 01009 // [29] Literal ::= '"' [^"]* '"' | "'" [^']* "'" 01010 // 01011 case CHARTYPE_QUOTE: // '\"' or '\'' 01012 { 01013 XMLCh qchar = ch; 01014 if (++currentOffset == endOffset) { 01015 return false; // REVISIT 01016 } 01017 01018 ch = data[currentOffset]; 01019 01020 XMLSize_t litOffset = currentOffset; 01021 while (ch != qchar) { 01022 if (++currentOffset == endOffset) { 01023 return false; // REVISIT 01024 } 01025 01026 ch = data[currentOffset]; 01027 } 01028 01029 addToken(tokens, XercesXPath::EXPRTOKEN_LITERAL); 01030 starIsMultiplyOperator = true; 01031 01032 dataBuffer.set(data + litOffset, currentOffset - litOffset); 01033 tokens->addElement(fStringPool->addOrFind(dataBuffer.getRawBuffer())); 01034 ++currentOffset; 01035 break; 01036 } 01037 // 01038 // [30] Number ::= Digits ('.' Digits?)? | '.' Digits 01039 // [31] Digits ::= [0-9]+ 01040 // 01041 case CHARTYPE_DIGIT: 01042 addToken(tokens, XercesXPath::EXPRTOKEN_NUMBER); 01043 starIsMultiplyOperator = true; 01044 currentOffset = scanNumber(data, endOffset, currentOffset, tokens); 01045 break; 01046 // 01047 // [36] VariableReference ::= '$' QName 01048 // 01049 case CHARTYPE_DOLLAR: 01050 if (++currentOffset == endOffset) { 01051 return false; // REVISIT 01052 } 01053 nameOffset = currentOffset; 01054 currentOffset = scanNCName(data, endOffset, currentOffset); 01055 01056 if (currentOffset == nameOffset) { 01057 return false; // REVISIT 01058 } 01059 01060 if (currentOffset < endOffset) { 01061 ch = data[currentOffset]; 01062 } 01063 else { 01064 ch = 0; 01065 } 01066 01067 dataBuffer.set(data + nameOffset, currentOffset - nameOffset); 01068 nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer()); 01069 prefixHandle = -1; 01070 01071 if (ch == chColon) { 01072 01073 prefixHandle = nameHandle; 01074 if (++currentOffset == endOffset) { 01075 return false; // REVISIT 01076 } 01077 nameOffset = currentOffset; 01078 currentOffset = scanNCName(data, endOffset, currentOffset); 01079 01080 if (currentOffset == nameOffset) { 01081 return false; // REVISIT 01082 } 01083 01084 dataBuffer.set(data + nameOffset, currentOffset - nameOffset); 01085 nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer()); 01086 } 01087 addToken(tokens, XercesXPath::EXPRTOKEN_VARIABLE_REFERENCE); 01088 starIsMultiplyOperator = true; 01089 tokens->addElement(prefixHandle); 01090 tokens->addElement(nameHandle); 01091 break; 01092 // 01093 // [37] NameTest ::= '*' | NCName ':' '*' | QName 01094 // [34] MultiplyOperator ::= '*' 01095 // 01096 case CHARTYPE_STAR: // '*' 01097 // 01098 // 3.7 Lexical Structure 01099 // 01100 // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or 01101 // an Operator, then a * must be recognized as a MultiplyOperator. 01102 // 01103 // Otherwise, the token must not be recognized as a MultiplyOperator. 01104 // 01105 if (starIsMultiplyOperator) { 01106 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MULT); 01107 starIsMultiplyOperator = false; 01108 } else { 01109 addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_ANY); 01110 starIsMultiplyOperator = true; 01111 } 01112 01113 ++currentOffset; 01114 break; 01115 // 01116 // NCName, QName and non-terminals 01117 // 01118 case CHARTYPE_NONASCII: // possibly a valid non-ascii 'Letter' (BaseChar | Ideographic) 01119 case CHARTYPE_LETTER: 01120 case CHARTYPE_UNDERSCORE: 01121 { 01122 // 01123 // 3.7 Lexical Structure 01124 // 01125 // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or 01126 // an Operator, then an NCName must be recognized as an OperatorName. 01127 // 01128 // If the character following an NCName (possibly after intervening ExprWhitespace) is (, 01129 // then the token must be recognized as a NodeType or a FunctionName. 01130 // 01131 // If the two characters following an NCName (possibly after intervening ExprWhitespace) 01132 // are ::, then the token must be recognized as an AxisName. 01133 // 01134 // Otherwise, the token must not be recognized as an OperatorName, a NodeType, a 01135 // FunctionName, or an AxisName. 01136 // 01137 // [33] OperatorName ::= 'and' | 'or' | 'mod' | 'div' 01138 // [38] NodeType ::= 'comment' | 'text' | 'processing-instruction' | 'node' 01139 // [35] FunctionName ::= QName - NodeType 01140 // [6] AxisName ::= (see above) 01141 // 01142 // [37] NameTest ::= '*' | NCName ':' '*' | QName 01143 // [5] NCName ::= (Letter | '_') (NCNameChar)* 01144 // [?] NCNameChar ::= Letter | Digit | '.' | '-' | '_' (ascii subset of 'NCNameChar') 01145 // [?] QName ::= (NCName ':')? NCName 01146 // [?] Letter ::= [A-Za-z] (ascii subset of 'Letter') 01147 // [?] Digit ::= [0-9] (ascii subset of 'Digit') 01148 // 01149 nameOffset = currentOffset; 01150 currentOffset = scanNCName(data, endOffset, currentOffset); 01151 if (currentOffset == nameOffset) { 01152 return false; // REVISIT 01153 } 01154 01155 if (currentOffset < endOffset) { 01156 ch = data[currentOffset]; 01157 } 01158 else { 01159 ch = 0; 01160 } 01161 01162 dataBuffer.set(data + nameOffset, currentOffset - nameOffset); 01163 nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer()); 01164 01165 bool isNameTestNCName = false; 01166 bool isAxisName = false; 01167 prefixHandle = -1; 01168 01169 if (ch == chColon) { 01170 01171 if (++currentOffset == endOffset) { 01172 return false; // REVISIT 01173 } 01174 01175 ch = data[currentOffset]; 01176 01177 if (ch == chAsterisk) { 01178 if (++currentOffset < endOffset) { 01179 ch = data[currentOffset]; 01180 } 01181 01182 isNameTestNCName = true; 01183 } else if (ch == chColon) { 01184 if (++currentOffset < endOffset) { 01185 ch = data[currentOffset]; 01186 } 01187 01188 isAxisName = true; 01189 } else { 01190 prefixHandle = nameHandle; 01191 nameOffset = currentOffset; 01192 currentOffset = scanNCName(data, endOffset, currentOffset); 01193 if (currentOffset == nameOffset) { 01194 return false; // REVISIT 01195 } 01196 if (currentOffset < endOffset) { 01197 ch = data[currentOffset]; 01198 } 01199 else { 01200 ch = 0; 01201 } 01202 01203 dataBuffer.set(data + nameOffset, currentOffset - nameOffset); 01204 nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer()); 01205 } 01206 } 01207 // 01208 // [39] ExprWhitespace ::= S 01209 // 01210 while (XMLChar1_0::isWhitespace(ch)) { 01211 if (++currentOffset == endOffset) { 01212 break; 01213 } 01214 ch = data[currentOffset]; 01215 } 01216 01217 // 01218 // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or 01219 // an Operator, then an NCName must be recognized as an OperatorName. 01220 // 01221 if (starIsMultiplyOperator) { 01222 if (nameHandle == fAndSymbol) { 01223 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_AND); 01224 starIsMultiplyOperator = false; 01225 } else if (nameHandle == fOrSymbol) { 01226 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_OR); 01227 starIsMultiplyOperator = false; 01228 } else if (nameHandle == fModSymbol) { 01229 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MOD); 01230 starIsMultiplyOperator = false; 01231 } else if (nameHandle == fDivSymbol) { 01232 addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_DIV); 01233 starIsMultiplyOperator = false; 01234 } else { 01235 return false; // REVISIT 01236 } 01237 01238 if (isNameTestNCName) { 01239 return false; // REVISIT - NCName:* where an OperatorName is required 01240 } else if (isAxisName) { 01241 return false; // REVISIT - AxisName:: where an OperatorName is required 01242 } 01243 break; 01244 } 01245 // 01246 // If the character following an NCName (possibly after intervening ExprWhitespace) is (, 01247 // then the token must be recognized as a NodeType or a FunctionName. 01248 // 01249 if (ch == chOpenParen && !isNameTestNCName && !isAxisName) { 01250 if (nameHandle == fCommentSymbol) { 01251 addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_COMMENT); 01252 } else if (nameHandle == fTextSymbol) { 01253 addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_TEXT); 01254 } else if (nameHandle == fPISymbol) { 01255 addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_PI); 01256 } else if (nameHandle == fNodeSymbol) { 01257 addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_NODE); 01258 } else { 01259 addToken(tokens, XercesXPath::EXPRTOKEN_FUNCTION_NAME); 01260 tokens->addElement(prefixHandle); 01261 tokens->addElement(nameHandle); 01262 } 01263 addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_PAREN); 01264 starIsMultiplyOperator = false; 01265 ++currentOffset; 01266 break; 01267 } 01268 01269 // 01270 // If the two characters following an NCName (possibly after intervening ExprWhitespace) 01271 // are ::, then the token must be recognized as an AxisName. 01272 // 01273 if (isAxisName || 01274 (ch == chColon && currentOffset + 1 < endOffset && 01275 data[currentOffset + 1] == chColon)) { 01276 01277 if (nameHandle == fAncestorSymbol) { 01278 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ANCESTOR); 01279 } else if (nameHandle == fAncestorOrSelfSymbol) { 01280 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF); 01281 } else if (nameHandle == fAttributeSymbol) { 01282 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE); 01283 } else if (nameHandle == fChildSymbol) { 01284 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_CHILD); 01285 } else if (nameHandle == fDescendantSymbol) { 01286 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_DESCENDANT); 01287 } else if (nameHandle == fDescendantOrSelfSymbol) { 01288 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF); 01289 } else if (nameHandle == fFollowingSymbol) { 01290 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_FOLLOWING); 01291 } else if (nameHandle == fFollowingSiblingSymbol) { 01292 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING); 01293 } else if (nameHandle == fNamespaceSymbol) { 01294 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_NAMESPACE); 01295 } else if (nameHandle == fParentSymbol) { 01296 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PARENT); 01297 } else if (nameHandle == fPrecedingSymbol) { 01298 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PRECEDING); 01299 } else if (nameHandle == fPrecedingSiblingSymbol) { 01300 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PRECEDING_SIBLING); 01301 } else if (nameHandle == fSelfSymbol) { 01302 addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_SELF); 01303 } else { 01304 return false; // REVISIT 01305 } 01306 01307 if (isNameTestNCName) { 01308 return false; // REVISIT - "NCName:* ::" where "AxisName ::" is required 01309 } 01310 01311 addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_COLON); 01312 starIsMultiplyOperator = false; 01313 if (!isAxisName) { 01314 currentOffset += 2; 01315 } 01316 break; 01317 } 01318 // 01319 // Otherwise, the token must not be recognized as an OperatorName, a NodeType, a 01320 // FunctionName, or an AxisName. 01321 // 01322 if (isNameTestNCName) { 01323 addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE); 01324 tokens->addElement(nameHandle); 01325 } else { 01326 addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_QNAME); 01327 tokens->addElement(prefixHandle); 01328 tokens->addElement(nameHandle); 01329 } 01330 01331 starIsMultiplyOperator = true; 01332 break; 01333 } 01334 default: 01335 { 01336 XMLCh str[2]= {ch, 0 }; 01337 ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_InvalidChar, str, tokens->getMemoryManager()); 01338 break; 01339 } 01340 } 01341 } 01342 01343 return true; 01344 } 01345 01346 01347 XMLSize_t XPathScanner::scanNCName(const XMLCh* const data, 01348 const XMLSize_t endOffset, 01349 XMLSize_t currentOffset) { 01350 01351 XMLCh ch = data[currentOffset]; 01352 01353 if (!XMLChar1_0::isFirstNCNameChar(ch)) { 01354 return currentOffset; 01355 } 01356 01357 while (++currentOffset < endOffset) { 01358 01359 ch = data[currentOffset]; 01360 01361 if (!XMLChar1_0::isNCNameChar(ch)) { 01362 break; 01363 } 01364 } 01365 01366 return currentOffset; 01367 } 01368 01369 01370 XMLSize_t XPathScanner::scanNumber(const XMLCh* const data, 01371 const XMLSize_t endOffset, 01372 XMLSize_t currentOffset, 01373 ValueVectorOf<int>* const tokens) { 01374 01375 XMLCh ch = data[currentOffset]; 01376 int whole = 0; 01377 int part = 0; 01378 01379 while (ch >= chDigit_0 && ch <= chDigit_9) { 01380 01381 whole = (whole * 10) + (ch - chDigit_0); 01382 01383 if (++currentOffset == endOffset) { 01384 break; 01385 } 01386 01387 ch = data[currentOffset]; 01388 } 01389 01390 if (ch == chPeriod) { 01391 01392 if (++currentOffset < endOffset) { 01393 01394 ch = data[currentOffset]; 01395 01396 while (ch >= chDigit_0 && ch <= chDigit_9) { 01397 01398 part = (part * 10) + (ch - chDigit_0); 01399 01400 if (++currentOffset == endOffset) { 01401 break; 01402 } 01403 01404 ch = data[currentOffset]; 01405 } 01406 01407 if (part != 0) { 01408 ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::XPath_FindSolution, tokens->getMemoryManager()); 01409 } 01410 } 01411 } 01412 01413 tokens->addElement(whole); 01414 tokens->addElement(part); 01415 01416 return currentOffset; 01417 } 01418 01419 01420 // --------------------------------------------------------------------------- 01421 // XPathScannerForSchema: Constructors and Destructor 01422 // --------------------------------------------------------------------------- 01423 XPathScannerForSchema::XPathScannerForSchema(XMLStringPool* const stringPool) 01424 : XPathScanner(stringPool) 01425 { 01426 } 01427 01428 01429 // --------------------------------------------------------------------------- 01430 // XPathScannerForSchema: Helper methods 01431 // --------------------------------------------------------------------------- 01432 void XPathScannerForSchema::addToken(ValueVectorOf<int>* const tokens, 01433 const int aToken) { 01434 01435 if (aToken == XercesXPath::EXPRTOKEN_ATSIGN || 01436 aToken == XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE || 01437 aToken == XercesXPath::EXPRTOKEN_AXISNAME_CHILD || 01438 //token == XercesXPath::EXPRTOKEN_AXISNAME_SELF || 01439 aToken == XercesXPath::EXPRTOKEN_DOUBLE_COLON || 01440 aToken == XercesXPath::EXPRTOKEN_NAMETEST_QNAME || 01441 //token == XercesXPath::EXPRTOKEN_NODETYPE_NODE || 01442 aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH || 01443 aToken == XercesXPath::EXPRTOKEN_PERIOD || 01444 aToken == XercesXPath::EXPRTOKEN_NAMETEST_ANY || 01445 aToken == XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE || 01446 aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH || 01447 aToken == XercesXPath::EXPRTOKEN_OPERATOR_UNION) { 01448 01449 tokens->addElement(aToken); 01450 return; 01451 } 01452 01453 ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_TokenNotSupported, tokens->getMemoryManager()); 01454 } 01455 01456 XERCES_CPP_NAMESPACE_END 01457