xsaxmlscanner.cpp

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

CPP
693
字号
            );        }    }    //  Now we can update the element stack to set the current element    //  decl. We expanded the stack above, but couldn't store the element    //  decl because we didn't know it yet.    fElemStack.setElement(elemDecl, fReaderMgr.getCurrentReaderNum());    fElemStack.setCurrentURI(uriId);    if (isRoot) {        fRootElemName = XMLString::replicate(qnameRawBuf, fMemoryManager);    }    //  Validate the element    if (fValidate) {        fValidator->validateElement(elemDecl);    }    // squirrel away the element's QName, so that we can do an efficient    // end-tag match    fElemStack.setCurrentSchemaElemName(fQNameBuf.getRawBuffer());    ComplexTypeInfo* typeinfo = (fValidate)        ? ((SchemaValidator*)fValidator)->getCurrentTypeInfo()        : ((SchemaElementDecl*) elemDecl)->getComplexTypeInfo();    if (typeinfo)    {        currentScope = typeinfo->getScopeDefined();        // switch grammar if the typeinfo has a different grammar        XMLCh* typeName = typeinfo->getTypeName();        int comma = XMLString::indexOf(typeName, chComma);        if (comma > 0)        {            XMLBufBid bbPrefix(&fBufMgr);            XMLBuffer& prefixBuf = bbPrefix.getBuffer();            prefixBuf.append(typeName, comma);            switchGrammar(prefixBuf.getRawBuffer(), laxThisOne);        }    }    fElemStack.setCurrentScope(currentScope);    // Set element next state    if (elemDepth >= fElemStateSize) {        resizeElemState();    }    fElemState[elemDepth] = 0;    fElemStack.setCurrentGrammar(fGrammar);    //  If this is the first element and we are validating, check the root    //  element.    if (!isRoot && parentValidation) {        fElemStack.addChild(elemDecl->getElementName(), true);    }    //  Now lets get the fAttrList filled in. This involves faulting in any    //  defaulted and fixed attributes and normalizing the values of any that    //  we got explicitly.    //    //  We update the attCount value with the total number of attributes, but    //  it goes in with the number of values we got during the raw scan of    //  explictly provided attrs above.    attCount = buildAttList(*fRawAttrList, attCount, elemDecl, *fAttrList);    if(attCount)    {        // clean up after ourselves:        // clear the map used to detect duplicate attributes        fUndeclaredAttrRegistryNS->removeAll();    }    // Since the element may have default values, call start tag now regardless if it is empty or not    // If we have a document handler, then tell it about this start tag    if (fDocHandler)    {        fDocHandler->startElement        (            *elemDecl, uriId, fPrefixBuf.getRawBuffer(), *fAttrList            , attCount, false, isRoot        );    } // may be where we output something...    //  If empty, validate content right now if we are validating and then    //  pop the element stack top. Else, we have to update the current stack    //  top's namespace mapping elements.    if (isEmpty)    {        // Pop the element stack back off since it'll never be used now        fElemStack.popTop();        // If validating, then insure that its legal to have no content        if (fValidate)        {            const int res = fValidator->checkContent(elemDecl, 0, 0);            if (res >= 0)            {                // REVISIT:  in the case of xsi:type, this may                // return the wrong string...                fValidator->emitError                (                    XMLValid::ElementNotValidForContent                    , elemDecl->getFullName()                    , elemDecl->getFormattedContentModel()                );            }        }        // If we have a doc handler, tell it about the end tag        if (fDocHandler)        {            fDocHandler->endElement            (                *elemDecl, uriId, isRoot, fPrefixBuf.getRawBuffer()            );        }        // If the elem stack is empty, then it was an empty root        if (isRoot) {            gotData = false;        }        else        {            // Restore the grammar            fGrammar = fElemStack.getCurrentGrammar();            fGrammarType = fGrammar->getGrammarType();            fValidator->setGrammar(fGrammar);            // Restore the validation flag            fValidate = fElemStack.getValidationFlag();        }    }    return true;}// ---------------------------------------------------------------------------//  XSAXMLScanner: XMLScanner virtual methods// ---------------------------------------------------------------------------//  This method will reset the scanner data structures, and related plugged//  in stuff, for a new scan session. We get the input source for the primary//  XML entity, create the reader for it, and push it on the stack so that//  upon successful return from here we are ready to go.void XSAXMLScanner::scanReset(const InputSource& src){    fGrammar = fSchemaGrammar;    fGrammarType = Grammar::SchemaGrammarType;    fRootGrammar = fSchemaGrammar;    fValidator->setGrammar(fGrammar);    // Reset validation    fValidate = true;    //  And for all installed handlers, send reset events. This gives them    //  a chance to flush any cached data.    if (fDocHandler)        fDocHandler->resetDocument();    if (fEntityHandler)        fEntityHandler->resetEntities();    if (fErrorReporter)        fErrorReporter->resetErrors();    // Clear out the id reference list    resetValidationContext();    // Reset the Root Element Name    if (fRootElemName) {        fMemoryManager->deallocate(fRootElemName);//delete [] fRootElemName;    }    fRootElemName = 0;    //  Reset the element stack, and give it the latest ids for the special    //  URIs it has to know about.    fElemStack.reset    (        fEmptyNamespaceId, fUnknownNamespaceId, fXMLNamespaceId, fXMLNSNamespaceId    );    if (!fSchemaNamespaceId)        fSchemaNamespaceId  = fURIStringPool->addOrFind(SchemaSymbols::fgURI_XSI);    // Reset some status flags    fInException = false;    fStandalone = false;    fErrorCount = 0;    fHasNoDTD = true;    fSeeXsi = false;    fDoNamespaces = true;    fDoSchema = true;    // Reset the validators    fSchemaValidator->reset();    fSchemaValidator->setErrorReporter(fErrorReporter);    fSchemaValidator->setExitOnFirstFatal(fExitOnFirstFatal);    fSchemaValidator->setGrammarResolver(fGrammarResolver);    //  Handle the creation of the XML reader object for this input source.    //  This will provide us with transcoding and basic lexing services.    XMLReader* newReader = fReaderMgr.createReader    (        src        , true        , XMLReader::RefFrom_NonLiteral        , XMLReader::Type_General        , XMLReader::Source_External        , fCalculateSrcOfs    );    if (!newReader) {        if (src.getIssueFatalErrorIfNotFound())            ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource, src.getSystemId(), fMemoryManager);        else            ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::Scan_CouldNotOpenSource_Warning, src.getSystemId(), fMemoryManager);    }    // Push this read onto the reader manager    fReaderMgr.pushReader(newReader, 0);    // and reset security-related things if necessary:    if(fSecurityManager != 0)     {        fEntityExpansionLimit = fSecurityManager->getEntityExpansionLimit();        fEntityExpansionCount = 0;    }    fElemCount = 0;    if (fUIntPoolRowTotal >= 32)     { // 8 KB tied up with validating attributes...        fAttDefRegistry->removeAll();        fUndeclaredAttrRegistryNS->removeAll();        recreateUIntPool();    }    else    {        // note that this will implicitly reset the values of the hashtables,        // though their buckets will still be tied up        resetUIntPool();    }}void XSAXMLScanner::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 (fSeeXsi)    {        //  Schema Xsi Type yyyy (e.g. xsi:type="yyyyy")        XMLBufBid bbXsi(&fBufMgr);        XMLBuffer& fXsiType = bbXsi.getBuffer();        QName attName(fMemoryManager);        for (index = 0; index < attCount; index++)        {            // each attribute has the prefix:suffix="value"            const KVStringPair* curPair = fRawAttrList->elementAt(index);            const XMLCh* rawPtr = curPair->getKey();            attName.setName(rawPtr, fEmptyNamespaceId);            const XMLCh* prefPtr = attName.getPrefix();            // 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 = attName.getLocalPart();                if (XMLString::equals(suffPtr, SchemaSymbols::fgXSI_TYPE)) {                    fXsiType.set(valuePtr);                }                else if (XMLString::equals(suffPtr, SchemaSymbols::fgATT_NILL)                         && XMLString::equals(valuePtr, SchemaSymbols::fgATTVAL_TRUE)) {                    ((SchemaValidator*)fValidator)->setNillable(true);                }            }        }        if (!fXsiType.isEmpty())        {            int colonPos = -1;            unsigned int uriId = resolveQName            (                fXsiType.getRawBuffer(), fPrefixBuf, ElemStack::Mode_Element, colonPos            );            ((SchemaValidator*)fValidator)->setXsiType(fPrefixBuf.getRawBuffer(), fXsiType.getRawBuffer() + colonPos + 1, uriId);        }    }}void XSAXMLScanner::switchGrammar( const XMLCh* const uriStr                                 , bool laxValidate){    Grammar* tempGrammar = 0;    if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {        tempGrammar = fSchemaGrammar;    }    else {        tempGrammar = fGrammarResolver->getGrammar(uriStr);    }    if (tempGrammar && tempGrammar->getGrammarType() == Grammar::SchemaGrammarType)    {        fGrammar = tempGrammar;        fGrammarType = Grammar::SchemaGrammarType;        fValidator->setGrammar(fGrammar);    }    else if(!laxValidate) {        fValidator->emitError(XMLValid::GrammarNotFound, uriStr);    }}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

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