schemavalidator.cpp

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

CPP
1,621
字号
                int colonPos = -1;                unsigned int uriId = getScanner()->resolveQName(attrValue, notationBuf, ElemStack::Mode_Element, colonPos);                notationBuf.set(getScanner()->getURIText(uriId));                notationBuf.append(chColon);                notationBuf.append(&attrValue[colonPos + 1]);                attDefDV->validate(notationBuf.getRawBuffer()                                 , context                                 , fMemoryManager);            }            else {                attDefDV->validate(attrValue                                 , context                                 , fMemoryManager);            }        }        catch (XMLException& idve) {            fErrorOccurred = true;            emitError (XMLValid::DatatypeError, idve.getType(), idve.getMessage());               }        catch(const OutOfMemoryException&)        {            throw;        }        catch (...) {            emitError(XMLValid::GenericError);            fMostRecentAttrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_ANYSIMPLETYPE);            fErrorOccurred = true;            throw;        }         fMostRecentAttrValidator = attDefDV;        // now we can look for ID's, entities, ...        // set up the entitydeclpool in ENTITYDatatypeValidator        // and the idreflist in ID/IDREFDatatypeValidator        // indicate if this attribute is of type ID        bool thisIsAnId = false;        if (attDefDVType == DatatypeValidator::List) {            DatatypeValidator* itemDTV = ((ListDatatypeValidator*)attDefDV)->getItemTypeDTV();            DatatypeValidator::ValidatorType itemDTVType = itemDTV->getType();            if (itemDTVType == DatatypeValidator::ID) {                thisIsAnId = true;            }            else if (itemDTVType == DatatypeValidator::IDREF) {                // if in prevalidatoin, do not add attDef to IDREFList                if (preValidation)                    //todo: when to setIdRefList back to non-null                    getScanner()->getValidationContext()->toCheckIdRefList(false);            }        }        else if (attDefDVType == DatatypeValidator::Union) {            DatatypeValidator *memberDTV = context->getValidatingMemberType();            // actual type for DOMTypeInfo is memberDTV            fMostRecentAttrValidator = memberDTV;            // no member datatype validator if there was an error            if(memberDTV)            {                DatatypeValidator::ValidatorType memberDTVType = memberDTV->getType();                if (memberDTVType == DatatypeValidator::ID) {                    thisIsAnId = true;                }                else if (memberDTVType == DatatypeValidator::IDREF) {                    // if in prevalidatoin, do not add attDef to IDREFList                    if (preValidation)                        getScanner()->getValidationContext()->toCheckIdRefList(false);                }            }        }        else if (attDefDVType == DatatypeValidator::ID) {            thisIsAnId = true;        }        else if (attDefDVType == DatatypeValidator::IDREF) {            // if in prevalidation, do not add attDef to IDREFList            if (preValidation)                getScanner()->getValidationContext()->toCheckIdRefList(false);        }        if (thisIsAnId) {            if (fSeenId) {                emitError                (                    XMLValid::MultipleIdAttrs                    , elemDecl->getFullName()                );                fErrorOccurred = true;            }            else                fSeenId = true;        }    }    if(fErrorOccurred) {        fMostRecentAttrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_ANYSIMPLETYPE);    }    fTrailing = false;}void SchemaValidator::validateElement(const   XMLElementDecl*  elemDef){    ComplexTypeInfo* elemTypeInfo = ((SchemaElementDecl*)elemDef)->getComplexTypeInfo();    fTypeStack->push(elemTypeInfo);    fCurrentDatatypeValidator = (elemTypeInfo)            ? elemTypeInfo->getDatatypeValidator()            : ((SchemaElementDecl*)elemDef)->getDatatypeValidator();    fErrorOccurred = false;    if (fXsiType) {        // handle "xsi:type" right here        DatatypeValidator *xsiTypeDV = 0;        unsigned int uri = fXsiType->getURI();        const XMLCh* localPart = fXsiType->getLocalPart();        if (uri != XMLElementDecl::fgInvalidElemId &&            uri != XMLElementDecl::fgPCDataElemId &&            uri != XMLContentModel::gEpsilonFakeId &&            uri != XMLContentModel::gEOCFakeId) {            // retrieve Grammar for the uri            const XMLCh* uriStr = getScanner()->getURIText(uri);            SchemaGrammar* sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(uriStr);            if (!sGrammar) {                // Check built-in simple types                if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {                    xsiTypeDV = fGrammarResolver->getDatatypeValidator(uriStr, localPart);                    if (!xsiTypeDV) {                        emitError(XMLValid::BadXsiType, fXsiType->getRawName());                        fErrorOccurred = true;                    }                    else {                        if (elemTypeInfo || (fCurrentDatatypeValidator                                  && !fCurrentDatatypeValidator->isSubstitutableBy(xsiTypeDV))) {                            // the type is not derived from ancestor                            emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());                            fErrorOccurred = true;                        }                        else {                            // the type is derived from ancestor                            if (((SchemaElementDecl*)elemDef)->getBlockSet() == SchemaSymbols::XSD_RESTRICTION) {                                emitError(XMLValid::NoSubforBlock, fXsiType->getRawName(), elemDef->getFullName());                                fErrorOccurred = true;                            }                            if (elemDef->hasAttDefs()) {                                // if we have an attribute but xsi:type's type is simple, we have a problem...                                emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());                                fErrorOccurred = true;                            }                        }                        fCurrentDatatypeValidator = xsiTypeDV;                    }                }                else {                    // Grammar not found                    emitError(XMLValid::GrammarNotFound, uriStr);                    fErrorOccurred = true;                }            }            else if (sGrammar->getGrammarType() != Grammar::SchemaGrammarType) {                emitError(XMLValid::GrammarNotFound, uriStr);                fErrorOccurred = true;            }            else {                // retrieve complexType registry and DatatypeValidator registry                RefHashTableOf<ComplexTypeInfo>* complexTypeRegistry = sGrammar->getComplexTypeRegistry();                if (!complexTypeRegistry) {                    emitError(XMLValid::BadXsiType, fXsiType->getRawName());                    fErrorOccurred = true;                }                else {                    // retrieve the typeInfo specified in xsi:type                    XMLBuffer aBuffer(1023, fMemoryManager);                    aBuffer.set(uriStr);                    aBuffer.append(chComma);                    aBuffer.append(localPart);                    ComplexTypeInfo* typeInfo = complexTypeRegistry->get(aBuffer.getRawBuffer());                    if (typeInfo) {                        // typeInfo is found                        if (typeInfo->getAbstract()) {                            emitError(XMLValid::NoAbstractInXsiType, aBuffer.getRawBuffer());                            fErrorOccurred = true;                        }                        else                        {                            if (elemTypeInfo)                            {                                ComplexTypeInfo* tempType = typeInfo;                                while (tempType) {                                    if (tempType == elemTypeInfo)                                        break;                                    tempType = tempType->getBaseComplexTypeInfo();                                }                                if (!tempType) {                                    emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());                                    fErrorOccurred = true;                                }                                else {                                    int derivationMethod = typeInfo->getDerivedBy();                                    if ((((SchemaElementDecl*)elemDef)->getBlockSet() & derivationMethod) != 0) {                                        emitError(XMLValid::NoSubforBlock, fXsiType->getRawName(), elemDef->getFullName());                                        fErrorOccurred = true;                                    }                                }                            }                            else                            {                                // if the original type is a simple type, check derivation ok.                                if (fCurrentDatatypeValidator && !fCurrentDatatypeValidator->isSubstitutableBy(typeInfo->getDatatypeValidator())) {                                    // the type is not derived from ancestor                                    emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());                                    fErrorOccurred = true;                                }                            }                            if (!fErrorOccurred)                            {                                fTypeStack->pop();                                fTypeStack->push(typeInfo);                                fCurrentDatatypeValidator = typeInfo->getDatatypeValidator();                            }                        }                    }                    else                    {                        // typeInfo not found                        xsiTypeDV = fGrammarResolver->getDatatypeValidator(uriStr, localPart);                        if (!xsiTypeDV) {                            emitError(XMLValid::BadXsiType, fXsiType->getRawName());                            fErrorOccurred = true;                        }                        else {                            if (fCurrentDatatypeValidator && !fCurrentDatatypeValidator->isSubstitutableBy(xsiTypeDV)) {                                // the type is not derived from ancestor                                emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());                                fErrorOccurred = true;                            }                            else {                                // the type is derived from ancestor                                if (((SchemaElementDecl*)elemDef)->getBlockSet() == SchemaSymbols::XSD_RESTRICTION) {                                    emitError(XMLValid::NoSubforBlock, fXsiType->getRawName(), elemDef->getFullName());                                    fErrorOccurred = true;                                }                                if (elemDef->hasAttDefs()) {                                    // if we have an attribute but xsi:type's type is simple, we have a problem...                                    emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());                                    fErrorOccurred = true;                                }                            }                            fCurrentDatatypeValidator = xsiTypeDV;                        }                    }                }            }        }        delete fXsiType;        fXsiType = 0;    }    else {        //        // xsi:type was not specified...        // If the corresponding type is abstract, detect an error        //        if (elemTypeInfo && elemTypeInfo->getAbstract()) {            emitError(XMLValid::NoUseAbstractType, elemDef->getFullName());            fErrorOccurred = true;        }    }    //    // Check whether this element is abstract.  If so, an error    //    int miscFlags = ((SchemaElementDecl*)elemDef)->getMiscFlags();    if ((miscFlags & SchemaSymbols::XSD_ABSTRACT) != 0) {        emitError(XMLValid::NoDirectUseAbstractElement, elemDef->getFullName());        fErrorOccurred = true;    }    //    // Check whether this element allows Nillable    //    if (fNil && (miscFlags & SchemaSymbols::XSD_NILLABLE) == 0 ) {        fNil = false;        emitError(XMLValid::NillNotAllowed, elemDef->getFullName());        fErrorOccurred = true;    }    fDatatypeBuffer.reset();    fTrailing = false;    fSeenId = false;}void SchemaValidator::preContentValidation(bool,                                           bool validateDefAttr){    //  Lets go through all the grammar in the GrammarResolver    //    and validate those that has not been validated yet    //    //  Lets enumerate all of the elements in the element decl pool    //    and put out an error for any that did not get declared.    //    We also check all of the attributes as well.    //    //  And enumerate all the complextype info in the grammar    //    and do Unique Particle Attribution Checking    RefHashTableOfEnumerator<Grammar> grammarEnum = fGrammarResolver->getGrammarEnumerator();    while (grammarEnum.hasMoreElements())    {        SchemaGrammar& sGrammar = (SchemaGrammar&) grammarEnum.nextElement();        if (sGrammar.getGrammarType() != Grammar::SchemaGrammarType || sGrammar.getValidated())             continue;        sGrammar.setValidated(true);

⌨️ 快捷键说明

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