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