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 + -
显示快捷键?