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