igxmlscanner2.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,601 行 · 第 1/5 页
CPP
1,601 行
else { // note that this will implicitly reset the values of the hashtables, // though their buckets will still be tied up resetUIntPool(); }}// This method is called between markup in content. It scans for character// data that is sent to the document handler. It watches for any markup// characters that would indicate that the character data has ended. It also// handles expansion of general and character entities.//// sendData() is a local static helper for this method which handles some// code that must be done in three different places here.void IGXMLScanner::sendCharData(XMLBuffer& toSend){ // If no data in the buffer, then nothing to do if (toSend.isEmpty()) return; // We do different things according to whether we are validating or // not. If not, its always just characters; else, it depends on the // current element's content model. if (fValidate) { // Get the raw data we need for the callback XMLCh* rawBuf = toSend.getRawBuffer(); unsigned int len = toSend.getLen(); // And see if the current element is a 'Children' style content model const ElemStack::StackElem* topElem = fElemStack.topElement(); // Get the character data opts for the current element XMLElementDecl::CharDataOpts charOpts = XMLElementDecl::AllCharData; if(fGrammar->getGrammarType() == Grammar::SchemaGrammarType) { // And see if the current element is a 'Children' style content model ComplexTypeInfo *currType = ((SchemaValidator*)fValidator)->getCurrentTypeInfo(); if(currType) { SchemaElementDecl::ModelTypes modelType = (SchemaElementDecl::ModelTypes) currType->getContentType(); if(modelType == SchemaElementDecl::Children) charOpts = XMLElementDecl::SpacesOk; else if(modelType == SchemaElementDecl::Empty) charOpts = XMLElementDecl::NoCharData; } } else // DTD grammar charOpts = topElem->fThisElement->getCharDataOpts(); if (charOpts == XMLElementDecl::NoCharData) { // They definitely cannot handle any type of char data fValidator->emitError(XMLValid::NoCharDataInCM); if(fGrammarType == Grammar::SchemaGrammarType) { if (getPSVIHandler()) { // REVISIT: // PSVIElement->setValidity(PSVIItem::VALIDITY_INVALID); } } } else if (fReaderMgr.getCurrentReader()->isAllSpaces(rawBuf, len)) { // Its all spaces. So, if they can take spaces, then send it // as ignorable whitespace. If they can handle any char data // send it as characters. if (charOpts == XMLElementDecl::SpacesOk) { if (fDocHandler) fDocHandler->ignorableWhitespace(rawBuf, len, false); } else if (charOpts == XMLElementDecl::AllCharData) { if (fGrammarType != Grammar::SchemaGrammarType) { if (fDocHandler) fDocHandler->docCharacters(rawBuf, len, false); } else { SchemaValidator *schemaValidator = (SchemaValidator *)fValidator; if (fNormalizeData) { DatatypeValidator* tempDV = ((SchemaValidator*) fValidator)->getCurrentDatatypeValidator(); if (tempDV && tempDV->getWSFacet() != DatatypeValidator::PRESERVE) { // normalize the character according to schema whitespace facet XMLBufBid bbtemp(&fBufMgr); XMLBuffer& tempBuf = bbtemp.getBuffer(); ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, rawBuf, tempBuf); rawBuf = tempBuf.getRawBuffer(); len = tempBuf.getLen(); } } // tell the schema validation about the character data for checkContent later schemaValidator->setDatatypeBuffer(rawBuf); // call all active identity constraints if (toCheckIdentityConstraint() && fICHandler->getMatcherCount()) fContent.append(rawBuf, len); if (fDocHandler) fDocHandler->docCharacters(rawBuf, len, false); } } } else { // If they can take any char data, then send it. Otherwise, they // can only handle whitespace and can't handle this stuff so // issue an error. if (charOpts == XMLElementDecl::AllCharData) { if (fGrammarType != Grammar::SchemaGrammarType) { if (fDocHandler) fDocHandler->docCharacters(rawBuf, len, false); } else { SchemaValidator *schemaValidator = (SchemaValidator*)fValidator; if (fNormalizeData) { DatatypeValidator* tempDV = ((SchemaValidator*) fValidator)->getCurrentDatatypeValidator(); if (tempDV && tempDV->getWSFacet() != DatatypeValidator::PRESERVE) { // normalize the character according to schema whitespace facet XMLBufBid bbtemp(&fBufMgr); XMLBuffer& tempBuf = bbtemp.getBuffer(); ((SchemaValidator*) fValidator)->normalizeWhiteSpace(tempDV, rawBuf, tempBuf); rawBuf = tempBuf.getRawBuffer(); len = tempBuf.getLen(); } } // tell the schema validation about the character data for checkContent later schemaValidator->setDatatypeBuffer(rawBuf); // call all active identity constraints if (toCheckIdentityConstraint() && fICHandler->getMatcherCount()) fContent.append(rawBuf, len); if (fDocHandler) fDocHandler->docCharacters(rawBuf, len, false); } } else { fValidator->emitError(XMLValid::NoCharDataInCM); if(fGrammarType == Grammar::SchemaGrammarType) { if (getPSVIHandler()) { // REVISIT: // PSVIAttribute->setValidity(PSVIItem::VALIDITY_INVALID); } } } } } else { // call all active identity constraints if (fGrammarType == Grammar::SchemaGrammarType) { if (toCheckIdentityConstraint() && fICHandler->getMatcherCount()) fContent.append(toSend.getRawBuffer(), toSend.getLen()); } // Always assume its just char data if not validating if (fDocHandler) fDocHandler->docCharacters(toSend.getRawBuffer(), toSend.getLen(), false); } // Reset buffer toSend.reset();}// This method is called with a key/value string pair that represents an// xmlns="yyy" or xmlns:xxx="yyy" attribute. This method will update the// current top of the element stack based on this data. We know that when// we get here, that it is one of these forms, so we don't bother confirming// it.//// But we have to ensure// 1. xxx is not xmlns// 2. if xxx is xml, then yyy must match XMLUni::fgXMLURIName, and vice versa// 3. yyy is not XMLUni::fgXMLNSURIName// 4. if xxx is not null, then yyy cannot be an empty string.void IGXMLScanner::updateNSMap(const XMLCh* const attrName , const XMLCh* const attrValue){ // We need a buffer to normalize the attribute value into XMLBufBid bbNormal(&fBufMgr); XMLBuffer& normalBuf = bbNormal.getBuffer(); // Normalize the value into the passed buffer. In this case, we don't // care about the return value. An error was issued for the error, which // is all we care about here. normalizeAttRawValue(attrName, attrValue, normalBuf); XMLCh* namespaceURI = normalBuf.getRawBuffer(); // We either have the default prefix (""), or we point it into the attr // name parameter. Note that the xmlns is not the prefix we care about // here. To us, the 'prefix' is really the local part of the attrName // parameter. // // Check 1. xxx is not xmlns // 2. if xxx is xml, then yyy must match XMLUni::fgXMLURIName, and vice versa // 3. yyy is not XMLUni::fgXMLNSURIName // 4. if xxx is not null, then yyy cannot be an empty string. const XMLCh* prefPtr = XMLUni::fgZeroLenString; const int colonOfs = XMLString::indexOf(attrName, chColon); if (colonOfs != -1) { prefPtr = &attrName[colonOfs + 1]; if (XMLString::equals(prefPtr, XMLUni::fgXMLNSString)) emitError(XMLErrs::NoUseOfxmlnsAsPrefix); else if (XMLString::equals(prefPtr, XMLUni::fgXMLString)) { if (!XMLString::equals(namespaceURI, XMLUni::fgXMLURIName)) emitError(XMLErrs::PrefixXMLNotMatchXMLURI); } if (!namespaceURI) emitError(XMLErrs::NoEmptyStrNamespace, attrName); else if(!*namespaceURI && fXMLVersion == XMLReader::XMLV1_0) emitError(XMLErrs::NoEmptyStrNamespace, attrName); } if (XMLString::equals(namespaceURI, XMLUni::fgXMLNSURIName)) emitError(XMLErrs::NoUseOfxmlnsURI); else if (XMLString::equals(namespaceURI, XMLUni::fgXMLURIName)) { if (!XMLString::equals(prefPtr, XMLUni::fgXMLString)) emitError(XMLErrs::XMLURINotMatchXMLPrefix); } // Ok, we have to get the unique id for the attribute value, which is the // URI that this value should be mapped to. The validator has the // namespace string pool, so we ask him to find or add this new one. Then // we ask the element stack to add this prefix to URI Id mapping. fElemStack.addPrefix ( prefPtr , fURIStringPool->addOrFind(namespaceURI) );}void IGXMLScanner::scanRawAttrListforNameSpaces(int attCount){ // Make an initial pass through the list and find any xmlns attributes or // schema attributes. // When we find one, send it off to be used to update the element stack's // namespace mappings. int index = 0; for (index = 0; index < attCount; index++) { // each attribute has the prefix:suffix="value" const KVStringPair* curPair = fRawAttrList->elementAt(index); const XMLCh* rawPtr = curPair->getKey(); // If either the key begins with "xmlns:" or its just plain // "xmlns", then use it to update the map. if (!XMLString::compareNString(rawPtr, XMLUni::fgXMLNSColonString, 6) || XMLString::equals(rawPtr, XMLUni::fgXMLNSString)) { const XMLCh* valuePtr = curPair->getValue(); updateNSMap(rawPtr, valuePtr); // if the schema URI is seen in the the valuePtr, set the boolean seeXsi if (XMLString::equals(valuePtr, SchemaSymbols::fgURI_XSI)) { fSeeXsi = true; } } } // walk through the list again to deal with "xsi:...." if (fDoSchema && fSeeXsi) { // Schema Xsi Type yyyy (e.g. xsi:type="yyyyy") XMLBufBid bbXsi(&fBufMgr); XMLBuffer& fXsiType = bbXsi.getBuffer(); for (index = 0; index < attCount; index++) { // each attribute has the prefix:suffix="value" const KVStringPair* curPair = fRawAttrList->elementAt(index); const XMLCh* rawPtr = curPair->getKey(); const XMLCh* prefPtr = XMLUni::fgZeroLenString; int colonInd = XMLString::indexOf(rawPtr, chColon); if (colonInd != -1) { fURIBuf.set(rawPtr, colonInd); prefPtr = fURIBuf.getRawBuffer(); } // if schema URI has been seen, scan for the schema location and uri // and resolve the schema grammar; or scan for schema type if (resolvePrefix(prefPtr, ElemStack::Mode_Attribute) == fSchemaNamespaceId) { const XMLCh* valuePtr = curPair->getValue(); const XMLCh* suffPtr = &rawPtr[colonInd + 1]; if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_SCHEMALOCACTION)) parseSchemaLocation(valuePtr); else if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION)) resolveSchemaGrammar(valuePtr, XMLUni::fgZeroLenString); if (XMLString::equals(suff
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?