dgxmlscanner.cpp

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

CPP
1,902
字号
            continue;        }    }    //  Make an initial pass through the list and find any xmlns attributes.    if (fDoNamespaces && attCount)      scanAttrListforNameSpaces(fAttrList, attCount, elemDecl);    if(attCount)    {        // clean up after ourselves:        // clear the map used to detect duplicate attributes        fUndeclaredAttrRegistry->removeAll();    }    //  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(attCount, elemDecl, *fAttrList);    //  If we have a document handler, then tell it about this start tag. We    //  don't have any URI id to send along, so send fEmptyNamespaceId. We also do not send    //  any prefix since its just one big name if we are not doing namespaces.    unsigned int uriId = fEmptyNamespaceId;    if (fDocHandler)    {        if (fDoNamespaces)        {            uriId = resolvePrefix            (                elemDecl->getElementName()->getPrefix()                , ElemStack::Mode_Element            );        }        fDocHandler->startElement        (            *elemDecl            , uriId            , (fDoNamespaces) ? elemDecl->getElementName()->getPrefix() : 0            , *fAttrList            , attCount            , false            , isRoot        );    }    //  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)    {        // If validating, then insure that its legal to have no content        if (fValidate)        {            const int res = fValidator->checkContent(elemDecl, 0, 0);            if (res >= 0)            {                fValidator->emitError                (                    XMLValid::ElementNotValidForContent                    , qnameRawBuf                    , elemDecl->getFormattedContentModel()                );            }        }        // If we have a doc handler, tell it about the end tag        if (fDocHandler)        {            fDocHandler->endElement            (                *elemDecl                , uriId                , isRoot                , (fDoNamespaces) ? elemDecl->getElementName()->getPrefix()                                  : XMLUni::fgZeroLenString            );        }        // Pop the element stack back off since it'll never be used now        fElemStack.popTop();        // If the elem stack is empty, then it was an empty root        if (isRoot)            gotData = false;    }    return true;}unsigned intDGXMLScanner::resolveQName(const   XMLCh* const qName                           ,       XMLBuffer&   prefixBuf                           , const short        mode                           ,       int&         prefixColonPos){    //  Lets split out the qName into a URI and name buffer first. The URI    //  can be empty.    prefixColonPos = XMLString::indexOf(qName, chColon);    if (prefixColonPos == -1)    {        //  Its all name with no prefix, so put the whole thing into the name        //  buffer. Then map the empty string to a URI, since the empty string        //  represents the default namespace. This will either return some        //  explicit URI which the default namespace is mapped to, or the        //  the default global namespace.        bool unknown = false;        prefixBuf.reset();        return fElemStack.mapPrefixToURI(XMLUni::fgZeroLenString, (ElemStack::MapModes) mode, unknown);    }    else    {        //  Copy the chars up to but not including the colon into the prefix        //  buffer.        prefixBuf.set(qName, prefixColonPos);        //  Watch for the special namespace prefixes. We always map these to        //  special URIs. 'xml' gets mapped to the official URI that its defined        //  to map to by the NS spec. xmlns gets mapped to a special place holder        //  URI that we define (so that it maps to something checkable.)        const XMLCh* prefixRawBuf = prefixBuf.getRawBuffer();        if (XMLString::equals(prefixRawBuf, XMLUni::fgXMLNSString)) {            // if this is an element, it is an error to have xmlns as prefix            if (mode == ElemStack::Mode_Element)                emitError(XMLErrs::NoXMLNSAsElementPrefix, qName);            return fXMLNSNamespaceId;        }        else if (XMLString::equals(prefixRawBuf, XMLUni::fgXMLString)) {            return  fXMLNamespaceId;        }        else        {            bool unknown = false;            unsigned int uriId = fElemStack.mapPrefixToURI(prefixRawBuf, (ElemStack::MapModes) mode, unknown);            if (unknown)                emitError(XMLErrs::UnknownPrefix, prefixRawBuf);            return uriId;        }    }}// ---------------------------------------------------------------------------//  DGXMLScanner: Grammar preparsing// ---------------------------------------------------------------------------Grammar* DGXMLScanner::loadGrammar(const   InputSource& src                                   , const short        grammarType                                   , const bool         toCache){    Grammar* loadedGrammar = 0;    try    {        fGrammarResolver->cacheGrammarFromParse(false);        fGrammarResolver->useCachedGrammarInParse(false);        fRootGrammar = 0;        if (fValScheme == Val_Auto) {            fValidate = true;        }        // Reset some status flags        fInException = false;        fStandalone = false;        fErrorCount = 0;        fHasNoDTD = true;        if (grammarType == Grammar::DTDGrammarType) {            loadedGrammar = loadDTDGrammar(src, toCache);        }        // Reset the reader manager to close all files, sockets, etc...        fReaderMgr.reset();    }    //  NOTE:    //    //  In all of the error processing below, the emitError() call MUST come    //  before the flush of the reader mgr, or it will fail because it tries    //  to find out the position in the XML source of the error.    catch(const XMLErrs::Codes)    {        // This is a 'first fatal error' type exit, so reset and fall through        fReaderMgr.reset();    }    catch(const XMLValid::Codes)    {        // This is a 'first fatal error' type exit, so reset and fall through        fReaderMgr.reset();    }    catch(const XMLException& excToCatch)    {        //  Emit the error and catch any user exception thrown from here. Make        //  sure in all cases we flush the reader manager.        fInException = true;        try        {            if (excToCatch.getErrorType() == XMLErrorReporter::ErrType_Warning)                emitError                (                    XMLErrs::DisplayErrorMessage                    , excToCatch.getMessage()                );            else if (excToCatch.getErrorType() >= XMLErrorReporter::ErrType_Fatal)                emitError                (                    XMLErrs::XMLException_Fatal                    , excToCatch.getType()                    , excToCatch.getMessage()                );            else                emitError                (                    XMLErrs::XMLException_Error                    , excToCatch.getType()                    , excToCatch.getMessage()                );        }        catch(const OutOfMemoryException&)        {            throw;        }        catch(...)        {            // Flush the reader manager and rethrow user's error            fReaderMgr.reset();            throw;        }        // If it returned, then reset the reader manager and fall through        fReaderMgr.reset();    }    catch(const OutOfMemoryException&)    {        throw;    }    catch(...)    {        // Reset and rethrow        fReaderMgr.reset();        throw;    }    return loadedGrammar;}Grammar* DGXMLScanner::loadDTDGrammar(const InputSource& src,                                      const bool toCache){    // Reset the validators    fDTDValidator->reset();    if (fValidatorFromUser)        fValidator->reset();    fDTDGrammar = new (fGrammarPoolMemoryManager) DTDGrammar(fGrammarPoolMemoryManager);    fGrammarResolver->putGrammar(fDTDGrammar);    fGrammar = fDTDGrammar;    fValidator->setGrammar(fGrammar);    //  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();    if (toCache) {        unsigned int sysId = fGrammarResolver->getStringPool()->addOrFind(src.getSystemId());        const XMLCh* sysIdStr = fGrammarResolver->getStringPool()->getValueForId(sysId);        fGrammarResolver->orphanGrammar(XMLUni::fgDTDEntityString);        ((XMLDTDDescription*) (fGrammar->getGrammarDescription()))->setSystemId(sysIdStr);        fGrammarResolver->putGrammar(fGrammar);    }    //  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        , false        , 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);    }    //  In order to make the processing work consistently, we have to    //  make this look like an external entity. So create an entity    //  decl and fill it in and push it with the reader, as happens    //  with an external entity. Put a janitor on it to insure it gets    //  cleaned up. The reader manager does not adopt them.    const XMLCh gDTDStr[] = { chLatin_D, chLatin_T, chLatin_D , chNull };    DTDEntityDecl* declDTD = new (fGrammarPoolMemoryManager) DTDEntityDecl(gDTDStr, false, fGrammarPoolMemoryManager);    declDTD->setSystemId(src.getSystemId());    Janitor<DTDEntityDecl> janDecl(declDTD);    // Mark this one as a throw at end    newReader->setThrowAtEnd(true);    // And push it onto the stack, with its pseudo name    fReaderMgr.pushReader(newReader, declDTD);    //  If we have a doc type handler and advanced callbacks are enabled,    //  call the doctype event.    if (fDocTypeHandler) {        // Create a dummy root        DTDElementDecl* rootDecl = new (fGrammarPoolMemoryManager) DTDElementDecl        (            gDTDStr            , fEmptyNamespaceId            , DTDElementDecl::Any            , fGrammarPoolMemoryManager        );        rootDecl->setCreateReason(DTDElementDecl::AsRootElem);        rootDecl->setExternalElemDeclaration(true);        Janitor<DTDElementDecl> janSrc(rootDecl);        fDocTypeHandler->doctypeDecl(*rootDecl, src.getPublicId(), src.getSystemId(), false, true);    }    // Create DTDScanner    DTDScanner dtdScanner    (        (DTDGrammar*)fGrammar        , fDocTypeHandler        , fGrammarPoolMemoryManager        , fMemoryManager    );    dtdScanner.setScannerInfo(this, &fReaderMgr, &fBufMgr);    // Tell it its not in an include section    dtdScanner.scanExtSubsetDecl(false, true);    if (fValidate) {        //  validate the DTD scan so far        fValidator->preContentValidation(false, true);    }    if (toCache)        fGrammarResolver->cacheGrammars();    return fDTDGrammar;}// ---------------------------------------------------------------------------//  DGXMLScanner: Private helper methods// ---------------------------------------------------------------------------//  This method handles the common initialization, to avoid having to do//  it redundantly in multiple constructors.void DGXMLScanner::commonInit(){    //  And we need one for the raw attribute scan. This just stores key/   

⌨️ 快捷键说明

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