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