dtdvalidator.cpp

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

CPP
690
字号
                        emitError(XMLValid::ReusedIDValue, pszTmpVal);                }                 else                {                    find = new (getScanner()->getMemoryManager()) XMLRefInfo                    (                        pszTmpVal                        , false                        , false                        , getScanner()->getMemoryManager()                    );                    getScanner()->getIDRefList()->put((void*)find->getRefName(), find);                }                //                //  Mark it declared or used, which might be redundant in some cases                //  but not worth checking                //                if (type == XMLAttDef::ID)                    find->setDeclared(true);                else {                    if (!preValidation) {                        find->setUsed(true);                    }                }            }        }         else if ((type == XMLAttDef::Entity) || (type == XMLAttDef::Entities))        {            //            //  If its refering to a entity, then look up the name in the            //  general entity pool. If not there, then its an error. If its            //  not an external unparsed entity, then its an error.            //            const XMLEntityDecl* decl = fDTDGrammar->getEntityDecl(pszTmpVal);            if (decl)            {                if (!decl->isUnparsed())                    emitError(XMLValid::BadEntityRefAttr, pszTmpVal, fullName);            }             else            {                emitError                (                    XMLValid::UnknownEntityRefAttr                    , fullName                    , pszTmpVal                );            }        }         else if ((type == XMLAttDef::Notation) || (type == XMLAttDef::Enumeration))        {            //            //  Make sure that this value maps to one of the enumeration or            //  notation values in the enumList parameter. We don't have to            //  look it up in the notation pool (if a notation) because we            //  will look up the enumerated values themselves. If they are in            //  the notation pool (after the DTD is parsed), then obviously            //  this value will be legal since it matches one of them.            //            if (!XMLString::isInList(pszTmpVal, enumList))                emitError(XMLValid::DoesNotMatchEnumList, pszTmpVal, fullName);        }        // If not doing multiple values, then we are done        if (!multipleValues)            break;        //        //  If we are at the end, then break out now, else move up to the        //  next char and update the base pointer.        //        if (alreadyCapped)            break;        valPtr++;        pszTmpVal = valPtr;    }}void DTDValidator::preContentValidation(bool reuseGrammar,                                        bool validateDefAttr){    //    //  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.    //    NameIdPoolEnumerator<DTDElementDecl> elemEnum = fDTDGrammar->getElemEnumerator();    while (elemEnum.hasMoreElements())    {        const DTDElementDecl& curElem = elemEnum.nextElement();        const DTDElementDecl::CreateReasons reason = curElem.getCreateReason();        //        //  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.        //        if (reason != XMLElementDecl::Declared)        {            if (reason == XMLElementDecl::AttList)            {                getScanner()->emitError                (                    XMLErrs::UndeclaredElemInAttList                    , curElem.getFullName()                );            }             else if (reason == XMLElementDecl::AsRootElem)            {                // It's ok that the root element is not declared in the DTD                /*                emitError                (                    XMLValid::UndeclaredElemInDocType                    , curElem.getFullName()                );*/            }             else if (reason == XMLElementDecl::InContentModel)            {                getScanner()->emitError                (                    XMLErrs::UndeclaredElemInCM                    , curElem.getFullName()                );            }            else            {                #if defined(XERCES_DEBUG)                  if(reuseGrammar && reason == XMLElementDecl::JustFaultIn){                  }                  else                      ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::DTD_UnknownCreateReason, getScanner()->getMemoryManager());                #endif            }        }        //        //  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.        //        //  4) XML1.0(3rd edition)        //        //     Validity constraint: One Notation Per Element Type        //     An element type MUST NOT have more than one NOTATION attribute specified.        //        //     Validity constraint: No Notation on Empty Element        //     For compatibility, an attribute of type NOTATION MUST NOT be declared on an element declared EMPTY.        //        //     Validity constraint: No Duplicate Tokens        //     The notation names in a single NotationType attribute declaration, as well as         //     the NmTokens in a single Enumeration attribute declaration, MUST all be distinct.        //        XMLAttDefList& attDefList = curElem.getAttDefList();        bool seenId = false;        bool seenNOTATION = false;        bool elemEmpty = (curElem.getModelType() == DTDElementDecl::Empty);        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)            {                if (seenNOTATION)                {                    emitError                    (                        XMLValid::ElemOneNotationAttr                      , curElem.getFullName()                    );                    break;                }                seenNOTATION = true;                // no notation attribute on empty element                if (elemEmpty)                {                    emitError                   (                      XMLValid::EmptyElemNotationAttr                    , curElem.getFullName()                    , curAttDef.getFullName()                    );                    break;                }                //go through enumeration list to check                // distinct                 // notation declaration                if (curAttDef.getEnumeration())                {                    checkTokenList(curAttDef, true);                }             }             else if (curAttDef.getType() == XMLAttDef::Enumeration )             {                //go through enumeration list to check                // distinct only                if (curAttDef.getEnumeration())                {                    checkTokenList(curAttDef, false);                }             }            // If it has a default/fixed value, then validate it            if (validateDefAttr && curAttDef.getValue())            {                validateAttrValue                (                    &curAttDef                    , curAttDef.getValue()                    , true                    , &curElem                );            }        }    }    //    //  And enumerate all of the general entities. If any of them    //  reference a notation, then make sure the notation exists.    //    NameIdPoolEnumerator<DTDEntityDecl> entEnum = fDTDGrammar->getEntityEnumerator();    while (entEnum.hasMoreElements())    {        const DTDEntityDecl& curEntity = entEnum.nextElement();        if (!curEntity.getNotationName())            continue;        // It has a notation name, so look it up        if (!fDTDGrammar->getNotationDecl(curEntity.getNotationName()))        {            emitError            (                XMLValid::NotationNotDeclared                , curEntity.getNotationName()            );        }    }}void DTDValidator::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.    //}////  We need to verify that all of its possible values//  (in the enum list) //   is distinct and//   refer to valid notations if toValidateNotation is set on//void DTDValidator::checkTokenList(const XMLAttDef&  curAttDef                                ,       bool        toValidateNotation){    XMLCh* list = XMLString::replicate(curAttDef.getEnumeration(), getScanner()->getMemoryManager());    ArrayJanitor<XMLCh> janList(list, getScanner()->getMemoryManager());    //    //  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;        //distinction check        //there should be no same token found in the remaining list        if (XMLString::isInList(lastPtr, listPtr))        {            emitError                (                XMLValid::AttrDupToken                , curAttDef.getFullName()                , lastPtr                );        }        if (toValidateNotation && !fDTDGrammar->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        lastPtr = listPtr;    }}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

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