XercesXPath.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:51k
- /*
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2001 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation, and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.ibm.com . For more information
- * on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
- /*
- * $Log: XercesXPath.cpp,v $
- * Revision 1.8 2003/05/18 14:02:09 knoaman
- * Memory manager implementation: pass per instance manager.
- *
- * Revision 1.7 2003/05/16 21:43:22 knoaman
- * Memory manager implementation: Modify constructors to pass in the memory manager.
- *
- * Revision 1.6 2003/05/15 18:59:34 knoaman
- * Partial implementation of the configurable memory manager.
- *
- * Revision 1.5 2002/12/20 22:10:48 tng
- * XML 1.1
- *
- * Revision 1.4 2002/12/04 18:21:23 knoaman
- * Identity constraint fix.
- *
- * Revision 1.3 2002/11/04 14:47:42 tng
- * C++ Namespace Support.
- *
- * Revision 1.2 2002/10/30 21:52:01 tng
- * [Bug 13641] compiler-generated copy-constructor for QName doesn't do the right thing.
- *
- * Revision 1.1.1.1 2002/02/01 22:22:51 peiyongz
- * sane_include
- *
- * Revision 1.3 2001/11/15 17:10:19 knoaman
- * Particle derivation checking support.
- *
- * Revision 1.2 2001/11/07 14:25:36 knoaman
- * Fix compliation error on Unix.
- *
- * Revision 1.1 2001/11/02 14:08:40 knoaman
- * Add support for identity constraints.
- *
- */
- // ---------------------------------------------------------------------------
- // Includes
- // ---------------------------------------------------------------------------
- #include <xercesc/validators/schema/identity/XercesXPath.hpp>
- #include <xercesc/validators/schema/identity/XPathSymbols.hpp>
- #include <xercesc/validators/schema/identity/XPathException.hpp>
- #include <xercesc/validators/schema/NamespaceScope.hpp>
- #include <xercesc/util/StringPool.hpp>
- #include <xercesc/util/Janitor.hpp>
- #include <xercesc/framework/XMLBuffer.hpp>
- #include <xercesc/internal/XMLReader.hpp>
- #include <xercesc/util/RuntimeException.hpp>
- XERCES_CPP_NAMESPACE_BEGIN
- // ---------------------------------------------------------------------------
- // Static data
- // ---------------------------------------------------------------------------
- const XMLByte XPathScanner::fASCIICharMap[128] =
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 2, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 2, 3, 4, 1, 5, 1, 1, 4, 6, 7, 8, 9, 10, 11, 12, 13,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 1, 16, 17, 18, 1,
- 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 1, 22, 1, 23,
- 1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 1, 24, 1, 1, 1
- };
- // ---------------------------------------------------------------------------
- // XercesNodeTest: Constructors and Destructor
- // ---------------------------------------------------------------------------
- XercesNodeTest::XercesNodeTest(const short aType,
- MemoryManager* const manager)
- : fType(aType)
- , fName(new (manager) QName(manager))
- {
- }
- XercesNodeTest::XercesNodeTest(const QName* const qName)
- : fType(QNAME)
- , fName(new (qName->getMemoryManager()) QName(*qName))
- {
- }
- XercesNodeTest::XercesNodeTest(const XMLCh* const prefix,
- const unsigned int uriId,
- MemoryManager* const manager)
- : fType(NAMESPACE)
- , fName(new (manager) QName(manager))
- {
- fName->setURI(uriId);
- fName->setPrefix(prefix);
- }
- XercesNodeTest::XercesNodeTest(const XercesNodeTest& other)
- : fType(other.fType)
- , fName(new ((other.fName)->getMemoryManager())QName(*other.fName))
- {
- }
- // ---------------------------------------------------------------------------
- // XercesNodeTest: Operators
- // ---------------------------------------------------------------------------
- XercesNodeTest& XercesNodeTest::operator=(const XercesNodeTest& other)
- {
- if (this == &other)
- return *this;
- fType = other.fType;
- fName->setValues(*(other.fName));
- return *this;
- }
- bool XercesNodeTest::operator ==(const XercesNodeTest& other) const {
- if (this == &other)
- return true;
- if (fType != other.fType)
- return false;
- return (*fName == *(other.fName));
- }
- bool XercesNodeTest::operator !=(const XercesNodeTest& other) const {
- return !operator==(other);
- }
- // ---------------------------------------------------------------------------
- // XercesStep: Constructors and Destructor
- // ---------------------------------------------------------------------------
- XercesStep::XercesStep(const unsigned short axisType, XercesNodeTest* const nodeTest)
- : fAxisType(axisType)
- , fNodeTest(nodeTest)
- {
- }
- XercesStep::XercesStep(const XercesStep& other)
- : fAxisType(other.fAxisType)
- , fNodeTest(0)
- {
- fNodeTest = new (other.fNodeTest->getName()->getMemoryManager()) XercesNodeTest(*(other.fNodeTest));
- }
- // ---------------------------------------------------------------------------
- // XercesStep: Operators
- // ---------------------------------------------------------------------------
- XercesStep& XercesStep::operator=(const XercesStep& other)
- {
- if (this == &other)
- return *this;
- fAxisType = other.fAxisType;
- *fNodeTest = *(other.fNodeTest);
- return *this;
- }
- bool XercesStep::operator==(const XercesStep& other) const {
- if (this == &other)
- return true;
- if (fAxisType != other.fAxisType)
- return false;
- if (fAxisType == XercesStep::CHILD ||
- fAxisType == XercesStep::ATTRIBUTE) {
- return (*fNodeTest == *(other.fNodeTest));
- }
- return true;
- }
- bool XercesStep::operator!=(const XercesStep& other) const {
- return !operator==(other);
- }
- // ---------------------------------------------------------------------------
- // XercesLocationPath: Constructors and Destructor
- // ---------------------------------------------------------------------------
- XercesLocationPath::XercesLocationPath(RefVectorOf<XercesStep>* const steps)
- : fSteps(steps)
- {
- }
- // ---------------------------------------------------------------------------
- // XercesLocationPath: Operators
- // ---------------------------------------------------------------------------
- bool XercesLocationPath::operator==(const XercesLocationPath& other) const {
- unsigned int stepsSize = fSteps->size();
- if (stepsSize != other.fSteps->size())
- return false;
- for (unsigned int i=0; i < stepsSize; i++) {
- if (*(fSteps->elementAt(i)) != *(other.fSteps->elementAt(i)))
- return false;
- }
- return true;
- }
- bool XercesLocationPath::operator!=(const XercesLocationPath& other) const {
- return !operator==(other);
- }
- // ---------------------------------------------------------------------------
- // XercesPath: Constructors and Destructor
- // ---------------------------------------------------------------------------
- XercesXPath::XercesXPath(const XMLCh* const xpathExpr,
- XMLStringPool* const stringPool,
- NamespaceScope* const scopeContext,
- const unsigned int emptyNamespaceId,
- const bool isSelector,
- MemoryManager* const manager)
- : fEmptyNamespaceId(emptyNamespaceId)
- , fExpression(0)
- , fLocationPaths(0)
- , fMemoryManager(manager)
- {
- try
- {
- fExpression = XMLString::replicate(xpathExpr, fMemoryManager);
- parseExpression(stringPool, scopeContext);
- if (isSelector) {
- checkForSelectedAttributes();
- }
- }
- catch(...) {
- cleanUp();
- throw;
- }
- }
- XercesXPath::~XercesXPath() {
- cleanUp();
- }
- // ---------------------------------------------------------------------------
- // XercesXPath: Operators
- // ---------------------------------------------------------------------------
- bool XercesXPath::operator==(const XercesXPath& other) const {
- unsigned int locPathSize = fLocationPaths->size();
- if (locPathSize != other.fLocationPaths->size())
- return false;
- for (unsigned int i=0; i < locPathSize; i++) {
- if (*(fLocationPaths->elementAt(i)) != *(other.fLocationPaths->elementAt(i)))
- return false;
- }
- return true;
- }
- bool XercesXPath::operator!=(const XercesXPath& other) const {
- return !operator==(other);
- }
- // ---------------------------------------------------------------------------
- // XercesPath: Helper methods
- // ---------------------------------------------------------------------------
- void XercesXPath::cleanUp() {
- fMemoryManager->deallocate(fExpression);//delete [] fExpression;
- delete fLocationPaths;
- }
- void XercesXPath::checkForSelectedAttributes() {
- // verify that an attribute is not selected
- unsigned int locSize = (fLocationPaths) ? fLocationPaths->size() : 0;
- for (unsigned int i = 0; i < locSize; i++) {
- XercesLocationPath* locPath = fLocationPaths->elementAt(i);
- unsigned int stepSize = locPath->getStepSize();
- if (stepSize) {
- if (locPath->getStep(stepSize - 1)->getAxisType() == XercesStep::ATTRIBUTE) {
- ThrowXML(XPathException, XMLExcepts::XPath_NoAttrSelector);
- }
- }
- }
- }
- void XercesXPath::parseExpression(XMLStringPool* const stringPool,
- NamespaceScope* const scopeContext) {
- unsigned int length = XMLString::stringLen(fExpression);
- if (!length) {
- return;
- }
- ValueVectorOf<int> tokens(16, fMemoryManager);
- XPathScannerForSchema scanner(stringPool);
- bool success = scanner.scanExpression(fExpression, 0, length, &tokens);
- bool firstTokenOfLocationPath=true;
- unsigned int tokenCount = tokens.size();
- RefVectorOf<XercesStep>* stepsVector = new (fMemoryManager) RefVectorOf<XercesStep>(16, true, fMemoryManager);
- Janitor<RefVectorOf<XercesStep> > janSteps(stepsVector);
- if (tokenCount) {
- fLocationPaths = new (fMemoryManager) RefVectorOf<XercesLocationPath>(8, true, fMemoryManager);
- }
- for (unsigned int i = 0; i < tokenCount; i++) {
- int aToken = tokens.elementAt(i);
- bool isNamespace=false;
- switch (aToken) {
- case XercesXPath::EXPRTOKEN_OPERATOR_UNION:
- {
- if (i == 0) {
- ThrowXML(XPathException, XMLExcepts::XPath_NoUnionAtStart);
- }
- int stepsSize = stepsVector->size();
- if (stepsSize == 0) {
- ThrowXML(XPathException, XMLExcepts::XPath_NoMultipleUnion);
- }
- fLocationPaths->addElement(new (fMemoryManager) XercesLocationPath(stepsVector));
- janSteps.orphan();
- stepsVector = new (fMemoryManager) RefVectorOf<XercesStep>(16, true, fMemoryManager);
- janSteps.reset(stepsVector);
- firstTokenOfLocationPath = true;
- }
- break;
- case XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE:
- {
- // consume "::" token and drop through
- i++;
- }
- case XercesXPath::EXPRTOKEN_ATSIGN:
- {
- // consume QName token
- if (i == tokenCount - 1) {
- ThrowXML(XPathException, XMLExcepts::XPath_MissingAttr);
- }
- aToken = tokens.elementAt(++i);
- if (aToken != XercesXPath::EXPRTOKEN_NAMETEST_QNAME
- && aToken!= XercesXPath::EXPRTOKEN_NAMETEST_ANY
- && aToken!= XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE) {
- ThrowXML(XPathException, XMLExcepts::XPath_ExpectedToken1);
- }
- bool isNamespaceAtt=false;
- switch (aToken) {
- case XercesXPath::EXPRTOKEN_NAMETEST_ANY:
- {
- XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::WILDCARD, fMemoryManager);
- XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::ATTRIBUTE, nodeTest);
- stepsVector->addElement(step);
- break;
- }
- case XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE:
- {
- isNamespaceAtt = true;
- }
- case XercesXPath::EXPRTOKEN_NAMETEST_QNAME:
- {
- aToken = tokens.elementAt(++i);
- const XMLCh* prefix = XMLUni::fgZeroLenString;
- unsigned int uri = fEmptyNamespaceId;
- if (scopeContext && aToken != -1) {
- prefix = stringPool->getValueForId(aToken);
- uri = scopeContext->getNamespaceForPrefix(prefix);
- }
- if (aToken != -1 && scopeContext && uri == fEmptyNamespaceId) {
- ThrowXML1(XPathException, XMLExcepts::XPath_PrefixNoURI, prefix);
- }
- if (isNamespaceAtt) {
- // build step
- XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(prefix, uri, fMemoryManager);
- XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::ATTRIBUTE, nodeTest);
- stepsVector->addElement(step);
- break;
- }
- aToken = tokens.elementAt(++i);
- const XMLCh* localPart = stringPool->getValueForId(aToken);
- QName aQName(prefix, localPart, uri, fMemoryManager);
- // build step
- XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(&aQName);
- XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::ATTRIBUTE, nodeTest);
- stepsVector->addElement(step);
- break;
- }
- }
- firstTokenOfLocationPath=false;
- break;
- }
- case XercesXPath::EXPRTOKEN_DOUBLE_COLON:
- {
- // should never have a bare double colon
- ThrowXML(XPathException, XMLExcepts::XPath_NoDoubleColon);
- }
- case XercesXPath::EXPRTOKEN_AXISNAME_CHILD:
- {
- // consume "::" token and drop through
- i++;
- if (i == tokenCount - 1) {
- ThrowXML(XPathException, XMLExcepts::XPath_ExpectedStep1);
- }
- firstTokenOfLocationPath=false;
- break;
- }
- case XercesXPath::EXPRTOKEN_NAMETEST_ANY:
- {
- XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::WILDCARD, fMemoryManager);
- XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::CHILD, nodeTest);
- stepsVector->addElement(step);
- firstTokenOfLocationPath = false;
- break;
- }
- case XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE:
- {
- isNamespace=true;
- }
- case XercesXPath::EXPRTOKEN_NAMETEST_QNAME:
- {
- // consume QName token
- aToken = tokens.elementAt(++i);
- const XMLCh* prefix = XMLUni::fgZeroLenString;
- unsigned int uri = fEmptyNamespaceId;
- if (scopeContext && aToken != -1) {
- prefix = stringPool->getValueForId(aToken);
- uri = scopeContext->getNamespaceForPrefix(prefix);
- }
- if (aToken != -1 && scopeContext && uri == fEmptyNamespaceId) {
- ThrowXML1(XPathException, XMLExcepts::XPath_PrefixNoURI, prefix);
- }
- if (isNamespace) {
- // build step
- XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(prefix, uri, fMemoryManager);
- XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::CHILD, nodeTest);
- stepsVector->addElement(step);
- break;
- }
- aToken = tokens.elementAt(++i);
- const XMLCh* localPart = stringPool->getValueForId(aToken);
- QName aQName(prefix, localPart, uri, fMemoryManager);
- // build step
- XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(&aQName);
- XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::CHILD, nodeTest);
- stepsVector->addElement(step);
- firstTokenOfLocationPath = false;
- break;
- }
- case XercesXPath::EXPRTOKEN_PERIOD:
- {
- // build step
- XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NODE, fMemoryManager);
- XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::SELF, nodeTest);
- stepsVector->addElement(step);
- if (firstTokenOfLocationPath && i+1 < tokenCount) {
- aToken = tokens.elementAt(i+1);
- if (aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH){
- if (++i == tokenCount - 1) {
- ThrowXML(XPathException, XMLExcepts::XPath_ExpectedStep2);
- }
- if (i+1 < tokenCount) {
- aToken = tokens.elementAt(i+1);
- if (aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH) {
- ThrowXML(XPathException, XMLExcepts::XPath_NoForwardSlash);
- }
- }
- // build step
- nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NODE, fMemoryManager);
- step = new (fMemoryManager) XercesStep(XercesStep::DESCENDANT, nodeTest);
- stepsVector->addElement(step);
- }
- }
- firstTokenOfLocationPath=false;
- break;
- }
- case XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH:
- {
- ThrowXML(XPathException, XMLExcepts::XPath_NoDoubleForwardSlash);
- }
- case XercesXPath::EXPRTOKEN_OPERATOR_SLASH:
- {
- if (i == 0) {
- ThrowXML(XPathException, XMLExcepts::XPath_NoForwardSlashAtStart);
- }
- // keep on truckin'
- if (firstTokenOfLocationPath) {
- ThrowXML(XPathException, XMLExcepts::XPath_NoSelectionOfRoot);
- }
- if (i == tokenCount - 1) {
- ThrowXML(XPathException, XMLExcepts::XPath_ExpectedStep3);
- }
- firstTokenOfLocationPath=false;
- break;
- }
- default:
- firstTokenOfLocationPath=false;
- }
- }
- int stepsSize = stepsVector->size();
- if (stepsSize == 0) {
- if (!fLocationPaths || fLocationPaths->size() == 0) {
- ThrowXML(XPathException, XMLExcepts::XPath_EmptyExpr);
- }
- else {
- ThrowXML(XPathException, XMLExcepts::XPath_NoUnionAtEnd);
- }
- }
- fLocationPaths->addElement(new (fMemoryManager) XercesLocationPath(stepsVector));
- janSteps.orphan();
- }
- // ---------------------------------------------------------------------------
- // XPathScanner: Constructors and Destructor
- // ---------------------------------------------------------------------------
- XPathScanner::XPathScanner(XMLStringPool* const stringPool)
- : fAndSymbol (0)
- , fOrSymbol(0)
- , fModSymbol(0)
- , fDivSymbol(0)
- , fCommentSymbol(0)
- , fTextSymbol(0)
- , fPISymbol(0)
- , fNodeSymbol(0)
- , fAncestorSymbol(0)
- , fAncestorOrSelfSymbol(0)
- , fAttributeSymbol(0)
- , fChildSymbol(0)
- , fDescendantSymbol(0)
- , fDescendantOrSelfSymbol(0)
- , fFollowingSymbol(0)
- , fFollowingSiblingSymbol(0)
- , fNamespaceSymbol(0)
- , fParentSymbol(0)
- , fPrecedingSymbol(0)
- , fPrecedingSiblingSymbol(0)
- , fSelfSymbol(0)
- , fStringPool(stringPool)
- {
- init();
- }
- // ---------------------------------------------------------------------------
- // XPathScanner: Helper methods
- // ---------------------------------------------------------------------------
- void XPathScanner::init() {
- fAndSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_AND);
- fOrSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_OR);
- fModSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_MOD);
- fDivSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DIV);
- fCommentSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_COMMENT);
- fTextSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_TEXT);
- fPISymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PI);
- fNodeSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_NODE);
- fAncestorSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ANCESTOR);
- fAncestorOrSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ANCESTOR_OR_SELF);
- fAttributeSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ATTRIBUTE);
- fChildSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_CHILD);
- fDescendantSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DESCENDANT);
- fDescendantOrSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DESCENDANT_OR_SELF);
- fFollowingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_FOLLOWING);
- fFollowingSiblingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_FOLLOWING_SIBLING);
- fNamespaceSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_NAMESPACE);
- fParentSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PARENT);
- fPrecedingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PRECEDING);
- fPrecedingSiblingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PRECEDING_SIBLING);
- fSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_SELF);
- }
- // ---------------------------------------------------------------------------
- // XPathScanner: Scan methods
- // ---------------------------------------------------------------------------
- bool XPathScanner::scanExpression(const XMLCh* const data,
- int currentOffset,
- const int endOffset,
- ValueVectorOf<int>* const tokens) {
- bool starIsMultiplyOperator = false;
- int nameOffset = -1;
- int nameHandle = -1;
- int prefixHandle = -1;
- XMLCh ch;
- XMLBuffer dataBuffer(128, tokens->getMemoryManager());
- while (true) {
- if (currentOffset == endOffset) {
- break;
- }
- ch = data[currentOffset];
- while (XMLChar1_0::isWhitespace(ch)) {
- if (++currentOffset == endOffset) {
- break;
- }
- ch = data[currentOffset];
- }
- if (currentOffset == endOffset) {
- break;
- }
- //
- // [28] ExprToken ::= '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::'
- // | NameTest | NodeType | Operator | FunctionName
- // | AxisName | Literal | Number | VariableReference
- //
- XMLByte chartype = (ch >= 0x80) ? CHARTYPE_NONASCII : fASCIICharMap[ch];
- switch (chartype) {
- case CHARTYPE_OPEN_PAREN: // '('
- addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_PAREN);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- case CHARTYPE_CLOSE_PAREN: // ')'
- addToken(tokens, XercesXPath::EXPRTOKEN_CLOSE_PAREN);
- starIsMultiplyOperator = true;
- ++currentOffset;
- break;
- case CHARTYPE_OPEN_BRACKET: // '['
- addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_BRACKET);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- case CHARTYPE_CLOSE_BRACKET: // ']'
- addToken(tokens, XercesXPath::EXPRTOKEN_CLOSE_BRACKET);
- starIsMultiplyOperator = true;
- ++currentOffset;
- break;
- //
- // [30] Number ::= Digits ('.' Digits?)? | '.' Digits
- // ^^^^^^^^^^
- //
- case CHARTYPE_PERIOD: // '.', '..' or '.' Digits
- if (currentOffset + 1 == endOffset) {
- addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
- starIsMultiplyOperator = true;
- currentOffset++;
- break;
- }
- ch = data[currentOffset + 1];
- if (ch == chPeriod) { // '..'
- addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_PERIOD);
- starIsMultiplyOperator = true;
- currentOffset += 2;
- } else if (ch >= chDigit_0 && ch <= chDigit_9) {
- addToken(tokens, XercesXPath::EXPRTOKEN_NUMBER);
- starIsMultiplyOperator = true;
- currentOffset = scanNumber(data, endOffset, currentOffset, tokens);
- } else if (ch == chForwardSlash) {
- addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
- starIsMultiplyOperator = true;
- currentOffset++;
- } else if (ch == chPipe) { // '|'
- addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
- starIsMultiplyOperator = true;
- currentOffset++;
- } else if (XMLChar1_0::isWhitespace(ch)) {
- do {
- if (++currentOffset == endOffset)
- break;
- ch = data[currentOffset];
- } while (XMLChar1_0::isWhitespace(ch));
- if (currentOffset == endOffset || ch == chPipe) {
- addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
- starIsMultiplyOperator = true;
- break;
- }
- } else {
- ThrowXML(XPathException, XMLExcepts::XPath_InvalidChar);
- }
- break;
- case CHARTYPE_ATSIGN: // '@'
- addToken(tokens, XercesXPath::EXPRTOKEN_ATSIGN);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- case CHARTYPE_COMMA: // ','
- addToken(tokens, XercesXPath::EXPRTOKEN_COMMA);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- case CHARTYPE_COLON: // '::'
- if (++currentOffset == endOffset) {
- return false; // REVISIT
- }
- ch = data[currentOffset];
- if (ch != chColon) {
- return false; // REVISIT
- }
- addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_COLON);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- case CHARTYPE_SLASH: // '/' and '//'
- if (++currentOffset == endOffset) {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_SLASH);
- starIsMultiplyOperator = false;
- break;
- }
- ch = data[currentOffset];
- if (ch == chForwardSlash) { // '//'
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH);
- starIsMultiplyOperator = false;
- ++currentOffset;
- } else {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_SLASH);
- starIsMultiplyOperator = false;
- }
- break;
- case CHARTYPE_UNION: // '|'
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_UNION);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- case CHARTYPE_PLUS: // '+'
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_PLUS);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- case CHARTYPE_MINUS: // '-'
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MINUS);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- case CHARTYPE_EQUAL: // '='
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_EQUAL);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- case CHARTYPE_EXCLAMATION: // '!='
- if (++currentOffset == endOffset) {
- return false; // REVISIT
- }
- ch = data[currentOffset];
- if (ch != chEqual) {
- return false; // REVISIT
- }
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_NOT_EQUAL);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- case CHARTYPE_LESS: // '<' and '<='
- if (++currentOffset == endOffset) {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS);
- starIsMultiplyOperator = false;
- break;
- }
- ch = data[currentOffset];
- if (ch == chEqual) { // '<='
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS_EQUAL);
- starIsMultiplyOperator = false;
- ++currentOffset;
- } else {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS);
- starIsMultiplyOperator = false;
- }
- break;
- case CHARTYPE_GREATER: // '>' and '>='
- if (++currentOffset == endOffset) {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER);
- starIsMultiplyOperator = false;
- break;
- }
- ch = data[currentOffset];
- if (ch == chEqual) { // '>='
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER_EQUAL);
- starIsMultiplyOperator = false;
- ++currentOffset;
- } else {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER);
- starIsMultiplyOperator = false;
- }
- break;
- //
- // [29] Literal ::= '"' [^"]* '"' | "'" [^']* "'"
- //
- case CHARTYPE_QUOTE: // '"' or '''
- {
- XMLCh qchar = ch;
- if (++currentOffset == endOffset) {
- return false; // REVISIT
- }
- ch = data[currentOffset];
- int litOffset = currentOffset;
- while (ch != qchar) {
- if (++currentOffset == endOffset) {
- return false; // REVISIT
- }
- ch = data[currentOffset];
- }
- addToken(tokens, XercesXPath::EXPRTOKEN_LITERAL);
- starIsMultiplyOperator = true;
- dataBuffer.set(data + litOffset, currentOffset - litOffset);
- tokens->addElement(fStringPool->addOrFind(dataBuffer.getRawBuffer()));
- ++currentOffset;
- break;
- }
- //
- // [30] Number ::= Digits ('.' Digits?)? | '.' Digits
- // [31] Digits ::= [0-9]+
- //
- case CHARTYPE_DIGIT:
- addToken(tokens, XercesXPath::EXPRTOKEN_NUMBER);
- starIsMultiplyOperator = true;
- currentOffset = scanNumber(data, endOffset, currentOffset, tokens);
- break;
- //
- // [36] VariableReference ::= '$' QName
- //
- case CHARTYPE_DOLLAR:
- if (++currentOffset == endOffset) {
- return false; // REVISIT
- }
- nameOffset = currentOffset;
- currentOffset = scanNCName(data, endOffset, currentOffset);
- if (currentOffset == nameOffset) {
- return false; // REVISIT
- }
- if (currentOffset < endOffset) {
- ch = data[currentOffset];
- }
- else {
- ch = 0;
- }
- dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
- nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
- prefixHandle = -1;
- if (ch == chColon) {
- prefixHandle = nameHandle;
- if (++currentOffset == endOffset) {
- return false; // REVISIT
- }
- nameOffset = currentOffset;
- currentOffset = scanNCName(data, endOffset, currentOffset);
- if (currentOffset == nameOffset) {
- return false; // REVISIT
- }
- dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
- nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
- }
- addToken(tokens, XercesXPath::EXPRTOKEN_VARIABLE_REFERENCE);
- starIsMultiplyOperator = true;
- tokens->addElement(prefixHandle);
- tokens->addElement(nameHandle);
- break;
- //
- // [37] NameTest ::= '*' | NCName ':' '*' | QName
- // [34] MultiplyOperator ::= '*'
- //
- case CHARTYPE_STAR: // '*'
- //
- // 3.7 Lexical Structure
- //
- // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or
- // an Operator, then a * must be recognized as a MultiplyOperator.
- //
- // Otherwise, the token must not be recognized as a MultiplyOperator.
- //
- if (starIsMultiplyOperator) {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MULT);
- starIsMultiplyOperator = false;
- } else {
- addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_ANY);
- starIsMultiplyOperator = true;
- }
- ++currentOffset;
- break;
- //
- // NCName, QName and non-terminals
- //
- case CHARTYPE_NONASCII: // possibly a valid non-ascii 'Letter' (BaseChar | Ideographic)
- case CHARTYPE_LETTER:
- case CHARTYPE_UNDERSCORE:
- //
- // 3.7 Lexical Structure
- //
- // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or
- // an Operator, then an NCName must be recognized as an OperatorName.
- //
- // If the character following an NCName (possibly after intervening ExprWhitespace) is (,
- // then the token must be recognized as a NodeType or a FunctionName.
- //
- // If the two characters following an NCName (possibly after intervening ExprWhitespace)
- // are ::, then the token must be recognized as an AxisName.
- //
- // Otherwise, the token must not be recognized as an OperatorName, a NodeType, a
- // FunctionName, or an AxisName.
- //
- // [33] OperatorName ::= 'and' | 'or' | 'mod' | 'div'
- // [38] NodeType ::= 'comment' | 'text' | 'processing-instruction' | 'node'
- // [35] FunctionName ::= QName - NodeType
- // [6] AxisName ::= (see above)
- //
- // [37] NameTest ::= '*' | NCName ':' '*' | QName
- // [5] NCName ::= (Letter | '_') (NCNameChar)*
- // [?] NCNameChar ::= Letter | Digit | '.' | '-' | '_' (ascii subset of 'NCNameChar')
- // [?] QName ::= (NCName ':')? NCName
- // [?] Letter ::= [A-Za-z] (ascii subset of 'Letter')
- // [?] Digit ::= [0-9] (ascii subset of 'Digit')
- //
- nameOffset = currentOffset;
- currentOffset = scanNCName(data, endOffset, currentOffset);
- if (currentOffset == nameOffset) {
- return false; // REVISIT
- }
- if (currentOffset < endOffset) {
- ch = data[currentOffset];
- }
- else {
- ch = 0;
- }
- dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
- nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
- bool isNameTestNCName = false;
- bool isAxisName = false;
- prefixHandle = -1;
- if (ch == chColon) {
- if (++currentOffset == endOffset) {
- return false; // REVISIT
- }
- ch = data[currentOffset];
- if (ch == chAsterisk) {
- if (++currentOffset < endOffset) {
- ch = data[currentOffset];
- }
- isNameTestNCName = true;
- } else if (ch == chColon) {
- if (++currentOffset < endOffset) {
- ch = data[currentOffset];
- }
- isAxisName = true;
- } else {
- prefixHandle = nameHandle;
- nameOffset = currentOffset;
- currentOffset = scanNCName(data, endOffset, currentOffset);
- if (currentOffset == nameOffset) {
- return false; // REVISIT
- }
- if (currentOffset < endOffset) {
- ch = data[currentOffset];
- }
- else {
- ch = 0;
- }
- dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
- nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
- }
- }
- //
- // [39] ExprWhitespace ::= S
- //
- while (XMLChar1_0::isWhitespace(ch)) {
- if (++currentOffset == endOffset) {
- break;
- }
- ch = data[currentOffset];
- }
- //
- // If there is a preceding token and the preceding token is not one of @, ::, (, [, , or
- // an Operator, then an NCName must be recognized as an OperatorName.
- //
- if (starIsMultiplyOperator) {
- if (nameHandle == fAndSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_AND);
- starIsMultiplyOperator = false;
- } else if (nameHandle == fOrSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_OR);
- starIsMultiplyOperator = false;
- } else if (nameHandle == fModSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MOD);
- starIsMultiplyOperator = false;
- } else if (nameHandle == fDivSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_DIV);
- starIsMultiplyOperator = false;
- } else {
- return false; // REVISIT
- }
- if (isNameTestNCName) {
- return false; // REVISIT - NCName:* where an OperatorName is required
- } else if (isAxisName) {
- return false; // REVISIT - AxisName:: where an OperatorName is required
- }
- break;
- }
- //
- // If the character following an NCName (possibly after intervening ExprWhitespace) is (,
- // then the token must be recognized as a NodeType or a FunctionName.
- //
- if (ch == chOpenParen && !isNameTestNCName && !isAxisName) {
- if (nameHandle == fCommentSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_COMMENT);
- } else if (nameHandle == fTextSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_TEXT);
- } else if (nameHandle == fPISymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_PI);
- } else if (nameHandle == fNodeSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_NODE);
- } else {
- addToken(tokens, XercesXPath::EXPRTOKEN_FUNCTION_NAME);
- tokens->addElement(prefixHandle);
- tokens->addElement(nameHandle);
- }
- addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_PAREN);
- starIsMultiplyOperator = false;
- ++currentOffset;
- break;
- }
- //
- // If the two characters following an NCName (possibly after intervening ExprWhitespace)
- // are ::, then the token must be recognized as an AxisName.
- //
- if (isAxisName ||
- (ch == chColon && currentOffset + 1 < endOffset &&
- data[currentOffset + 1] == chColon)) {
- if (nameHandle == fAncestorSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ANCESTOR);
- } else if (nameHandle == fAncestorOrSelfSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF);
- } else if (nameHandle == fAttributeSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE);
- } else if (nameHandle == fChildSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_CHILD);
- } else if (nameHandle == fDescendantSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_DESCENDANT);
- } else if (nameHandle == fDescendantOrSelfSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF);
- } else if (nameHandle == fFollowingSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_FOLLOWING);
- } else if (nameHandle == fFollowingSiblingSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING);
- } else if (nameHandle == fNamespaceSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_NAMESPACE);
- } else if (nameHandle == fParentSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PARENT);
- } else if (nameHandle == fPrecedingSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PRECEDING);
- } else if (nameHandle == fPrecedingSiblingSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PRECEDING_SIBLING);
- } else if (nameHandle == fSelfSymbol) {
- addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_SELF);
- } else {
- return false; // REVISIT
- }
- if (isNameTestNCName) {
- return false; // REVISIT - "NCName:* ::" where "AxisName ::" is required
- }
- addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_COLON);
- starIsMultiplyOperator = false;
- if (!isAxisName) {
- currentOffset += 2;
- }
- break;
- }
- //
- // Otherwise, the token must not be recognized as an OperatorName, a NodeType, a
- // FunctionName, or an AxisName.
- //
- if (isNameTestNCName) {
- addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE);
- tokens->addElement(nameHandle);
- } else {
- addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_QNAME);
- tokens->addElement(prefixHandle);
- tokens->addElement(nameHandle);
- }
- starIsMultiplyOperator = true;
- break;
- }
- }
- return true;
- }
- int XPathScanner::scanNCName(const XMLCh* const data,
- const int endOffset,
- int currentOffset) {
- XMLCh ch = data[currentOffset];
- if (!XMLChar1_0::isXMLLetter(ch) && ch != chUnderscore) {
- return currentOffset;
- }
- while (++currentOffset < endOffset) {
- ch = data[currentOffset];
- if (ch == chColon || !XMLChar1_0::isNameChar(ch)) {
- break;
- }
- }
- return currentOffset;
- }
- int XPathScanner::scanNumber(const XMLCh* const data,
- const int endOffset,
- int currentOffset,
- ValueVectorOf<int>* const tokens) {
- XMLCh ch = data[currentOffset];
- int whole = 0;
- int part = 0;
- while (ch >= chDigit_0 && ch <= chDigit_9) {
- whole = (whole * 10) + (ch - chDigit_0);
- if (++currentOffset == endOffset) {
- break;
- }
- ch = data[currentOffset];
- }
- if (ch == chPeriod) {
- if (++currentOffset < endOffset) {
- int start = currentOffset;
- ch = data[currentOffset];
- while (ch >= chDigit_0 && ch <= chDigit_9) {
- part = (part * 10) + (ch - chDigit_0);
- if (++currentOffset == endOffset) {
- break;
- }
- ch = data[currentOffset];
- }
- if (part != 0) {
- ThrowXML(RuntimeException, XMLExcepts::XPath_FindSolution);
- }
- }
- }
- tokens->addElement(whole);
- tokens->addElement(part);
- return currentOffset;
- }
- // ---------------------------------------------------------------------------
- // XPathScannerForSchema: Constructors and Destructor
- // ---------------------------------------------------------------------------
- XPathScannerForSchema::XPathScannerForSchema(XMLStringPool* const stringPool)
- : XPathScanner(stringPool)
- {
- }
- // ---------------------------------------------------------------------------
- // XPathScannerForSchema: Helper methods
- // ---------------------------------------------------------------------------
- void XPathScannerForSchema::addToken(ValueVectorOf<int>* const tokens,
- const int aToken) {
- if (aToken == XercesXPath::EXPRTOKEN_ATSIGN ||
- aToken == XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE ||
- aToken == XercesXPath::EXPRTOKEN_AXISNAME_CHILD ||
- //token == XercesXPath::EXPRTOKEN_AXISNAME_SELF ||
- aToken == XercesXPath::EXPRTOKEN_DOUBLE_COLON ||
- aToken == XercesXPath::EXPRTOKEN_NAMETEST_QNAME ||
- //token == XercesXPath::EXPRTOKEN_NODETYPE_NODE ||
- aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH ||
- aToken == XercesXPath::EXPRTOKEN_PERIOD ||
- aToken == XercesXPath::EXPRTOKEN_NAMETEST_ANY ||
- aToken == XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE ||
- aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH ||
- aToken == XercesXPath::EXPRTOKEN_OPERATOR_UNION) {
- tokens->addElement(aToken);
- return;
- }
- ThrowXML(XPathException, XMLExcepts::XPath_TokenNotSupported);
- }
- XERCES_CPP_NAMESPACE_END
- /**
- * End of file XercesPath.cpp
- */