schemavalidator.cpp

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

CPP
1,621
字号
        RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = sGrammar.getElemEnumerator();        while (elemEnum.hasMoreElements())        {            SchemaElementDecl& curElem = elemEnum.nextElement();            //  First check if declared or not            //            //  See if this element decl was ever marked as declared. If            //  not, then put out an error. In some cases its just            //  a warning, such as being referenced in a content model.            //            const SchemaElementDecl::CreateReasons reason = curElem.getCreateReason();            if (reason != XMLElementDecl::Declared)            {                if (reason == XMLElementDecl::AttList)                {                    getScanner()->emitError                    (                        XMLErrs::UndeclaredElemInAttList                        , curElem.getFullName()                    );                }                 else if (reason == XMLElementDecl::AsRootElem)                {                    emitError                    (                        XMLValid::UndeclaredElemInDocType                        , curElem.getFullName()                    );                }                 else if (reason == XMLElementDecl::InContentModel)                {                    getScanner()->emitError                    (                        XMLErrs::UndeclaredElemInCM                        , curElem.getFullName()                    );                }                else                {                }            }            //            //  Then check all of the attributes of the current element.            //  We check for:            //            //  1) Multiple ID attributes            //  2) That all of the default values of attributes are            //      valid for their type.            //  3) That for any notation types, that their lists            //      of possible values refer to declared notations.            //            if (curElem.hasAttDefs()) {                XMLAttDefList& attDefList = curElem.getAttDefList();                bool seenId = false;                for(unsigned int i=0; i<attDefList.getAttDefCount(); i++)                {                    const XMLAttDef& curAttDef = attDefList.getAttDef(i);                    if (curAttDef.getType() == XMLAttDef::ID)                    {                        if (seenId)                        {                            emitError                            (                                XMLValid::MultipleIdAttrs                                , curElem.getFullName()                            );                            break;                        }                        seenId = true;                    }                     else if (curAttDef.getType() == XMLAttDef::Notation && curAttDef.getEnumeration())                    {                        //                        //  We need to verify that all of its possible values                        //  (in the enum list) refer to valid notations.                        //                        XMLCh* list = XMLString::replicate(curAttDef.getEnumeration(), fMemoryManager);                        ArrayJanitor<XMLCh> janList(list, fMemoryManager);                        //                        //  Search forward for a space or a null. If a null,                        //  we are done. If a space, cap it and look it up.                        //                        bool    breakFlag = false;                        XMLCh*  listPtr = list;                        XMLCh*  lastPtr = listPtr;                        while (true)                        {                            while (*listPtr && (*listPtr != chSpace))                                listPtr++;                            //                            //  If at the end, indicate we need to break after                            //  this one. Else, cap it off here.                            //                            if (!*listPtr)                                breakFlag = true;                            else                                *listPtr = chNull;                            if (!sGrammar.getNotationDecl(lastPtr))                            {                                emitError                                (                                    XMLValid::UnknownNotRefAttr                                    , curAttDef.getFullName()                                    , lastPtr                                );                            }                            // Break out if we hit the end last time                            if (breakFlag)                                break;                            // Else move upwards and try again                            listPtr++;                            lastPtr = listPtr;                        }                    }                    // If it has a default/fixed value, then validate it                    if (validateDefAttr && curAttDef.getValue())                    {                        validateAttrValue                        (                            &curAttDef                            , curAttDef.getValue()                            , true                            , &curElem                        );                    }                }            }        }        //  For each complex type info, check the Unique Particle Attribution        if (getScanner()->getValidationSchemaFullChecking()) {            RefHashTableOf<ComplexTypeInfo>* complexTypeRegistry = sGrammar.getComplexTypeRegistry();            RefHashTableOfEnumerator<ComplexTypeInfo> complexTypeEnum(complexTypeRegistry, false, fMemoryManager);            while (complexTypeEnum.hasMoreElements())            {                ComplexTypeInfo& curTypeInfo = complexTypeEnum.nextElement();                curTypeInfo.checkUniqueParticleAttribution(&sGrammar, fGrammarResolver, fGrammarResolver->getStringPool(), this);                checkParticleDerivation(&sGrammar, &curTypeInfo);                checkRefElementConsistency(&sGrammar, &curTypeInfo);            }            RefHashTableOf<XercesGroupInfo>* groupInfoRegistry = sGrammar.getGroupInfoRegistry();            RefHashTableOfEnumerator<XercesGroupInfo> groupEnum(groupInfoRegistry, false, fMemoryManager);            while (groupEnum.hasMoreElements()) {                XercesGroupInfo& curGroup = groupEnum.nextElement();                XercesGroupInfo* baseGroup = curGroup.getBaseGroup();                if (baseGroup) {                    try {                        checkParticleDerivationOk(&sGrammar, curGroup.getContentSpec(), curGroup.getScope(),                                                  baseGroup->getContentSpec(), baseGroup->getScope());                    }                    catch (const XMLException& excep) {                        fSchemaErrorReporter.emitError(XMLErrs::DisplayErrorMessage, XMLUni::fgXMLErrDomain, curGroup.getLocator(), excep.getMessage(), 0, 0, 0, fMemoryManager);					}                }                if (curGroup.getCheckElementConsistency())                    checkRefElementConsistency(&sGrammar, 0, &curGroup);            }        }    }}void SchemaValidator::postParseValidation(){    //    //  At this time, there is nothing to do here. The scanner itself handles    //  ID/IDREF validation, since that is the same no matter what kind of    //  validator.    //}// ---------------------------------------------------------------------------//  SchemaValidator: Validator method// ---------------------------------------------------------------------------// Do Schema Normalization depends on the WhiteSpace Facet// preserve : No normalization is done// replace  : All occurrences of #x9 (tab), #xA (linefeed) and #xD (carriage return)//            are replaced with #x20 (space).// collapse : Subsequent to the replacements specified above under replace,//            contiguous sequences of #x20s are collapsed to a single #x20,//            and initial and/or final #x20s are deleted.//void SchemaValidator::normalizeWhiteSpace(DatatypeValidator* dV, const XMLCh* const value, XMLBuffer& toFill){    short wsFacet = dV->getWSFacet();    toFill.reset();    //empty string    if (!*value)        return;    enum States    {        InWhitespace        , InContent    };    States curState = InContent;    //  Loop through the chars of the source value and normalize it    //  according to the whitespace facet    bool firstNonWS = false;    XMLCh nextCh;    const XMLCh* srcPtr = value;    XMLReader* fCurReader = getReaderMgr()->getCurrentReader();    if ((wsFacet==DatatypeValidator::COLLAPSE) && fTrailing)        toFill.append(chSpace);    while (*srcPtr)    {        nextCh = *srcPtr;        if (wsFacet == DatatypeValidator::REPLACE)        {            if (fCurReader->isWhitespace(nextCh))                nextCh = chSpace;        }        else // COLLAPSE case        {            if (curState == InWhitespace)            {                if (!fCurReader->isWhitespace(nextCh))                {                    if (firstNonWS)                        toFill.append(chSpace);                    curState = InContent;                    firstNonWS = true;                }                else                {                    srcPtr++;                    continue;                }            }            else if (curState == InContent)            {                if (fCurReader->isWhitespace(nextCh))                {                    curState = InWhitespace;                    srcPtr++;                    continue;                }                firstNonWS = true;            }        }        // Add this char to the target buffer        toFill.append(nextCh);        // And move up to the next character in the source        srcPtr++;    }    if (fCurReader->isWhitespace(*(srcPtr-1)))        fTrailing = true;}// ---------------------------------------------------------------------------//  SchemaValidator: Particle Derivation Checking// ---------------------------------------------------------------------------void SchemaValidator::checkRefElementConsistency(SchemaGrammar* const currentGrammar,                                                 const ComplexTypeInfo* const curTypeInfo,                                                 const XercesGroupInfo* const curGroup) {    unsigned int elemCount = (curTypeInfo) ? curTypeInfo->elementCount() : curGroup->elementCount();    int elemScope = (curTypeInfo) ? curTypeInfo->getScopeDefined() : curGroup->getScope();    XSDLocator* typeInfoLocator = (curTypeInfo) ? curTypeInfo->getLocator() : curGroup->getLocator();    for (unsigned int i=0; i < elemCount; i++) {        const SchemaElementDecl* elemDecl = (curTypeInfo) ? curTypeInfo->elementAt(i) : curGroup->elementAt(i);        if (elemDecl->isGlobalDecl()) {            unsigned int elemURI = elemDecl->getURI();            const XMLCh* elemName = elemDecl->getBaseName();            const SchemaElementDecl* other = (SchemaElementDecl*)                currentGrammar->getElemDecl(elemURI, elemName, 0, elemScope);            if (other                && (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo() ||                    elemDecl->getDatatypeValidator() != other->getDatatypeValidator())) {                fSchemaErrorReporter.emitError(XMLErrs::DuplicateElementDeclaration,                                               XMLUni::fgXMLErrDomain, typeInfoLocator, elemName, 0, 0, 0, fMemoryManager);                continue;            }            RefHash2KeysTableOf<ElemVector>* validSubsGroups = currentGrammar->getValidSubstitutionGroups();            ValueVectorOf<SchemaElementDecl*>* subsElements = validSubsGroups->get(elemName, elemURI);            if (subsElements) {                unsigned subsElemSize = subsElements->size();                for (unsigned int j=0; j < subsElemSize; j++) {                    SchemaElementDecl* subsElem = subsElements->elementAt(j);                    const XMLCh* subsElemName = subsElem->getBaseName();                    other = (SchemaElementDecl*)                        currentGrammar->getElemDecl(subsElem->getURI(), subsElemName, 0, elemScope);                    if (other                        && (subsElem->getComplexTypeInfo() != other->getComplexTypeInfo()                            || subsElem->getDatatypeValidator() != other->getDatatypeValidator())) {                        fSchemaErrorReporter.emitError(XMLErrs::DuplicateElementDeclaration,                                                       XMLUni::fgXMLErrDomain, typeInfoLocator, elemName, 0, 0, 0, fMemoryManager);

⌨️ 快捷键说明

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