xercesxpath.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,455 行 · 第 1/4 页

CPP
1,455
字号
// ---------------------------------------------------------------------------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 {                ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_InvalidChar, tokens->getMemoryManager());            }            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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?