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 + -
显示快捷键?