schemavalidator.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,621 行 · 第 1/5 页
CPP
1,621 行
}SchemaValidator::~SchemaValidator(){ delete fXsiType; delete fTypeStack; if (fNotationBuf) delete fNotationBuf;}// ---------------------------------------------------------------------------// SchemaValidator: Implementation of the XMLValidator interface// ---------------------------------------------------------------------------int SchemaValidator::checkContent (XMLElementDecl* const elemDecl , QName** const children , const unsigned int childCount){ fErrorOccurred = false; fElemIsSpecified = false; // // Look up the element id in our element decl pool. This will get us // the element decl in our own way of looking at them. // if (!elemDecl) ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Val_InvalidElemId, fMemoryManager); // // Get the content spec type of this element. This will tell us what // to do to validate it. // // the top of the type stack always knows best... ComplexTypeInfo* currType = fTypeStack->pop(); const SchemaElementDecl::ModelTypes modelType = (currType) ? (SchemaElementDecl::ModelTypes)(currType->getContentType()) : ((SchemaElementDecl*)elemDecl)->getModelType(); if (modelType == SchemaElementDecl::Empty) { // // We can do this one here. It cannot have any children. If it does // we return 0 as the index of the first bad child. // if (childCount) { fErrorOccurred = true; return 0; } } else if ((modelType == SchemaElementDecl::Mixed_Simple) || (modelType == SchemaElementDecl::Mixed_Complex) || (modelType == SchemaElementDecl::Children)) { // if nillable, it's an error to have value // XML Schema REC: Validation Rule: Element Locally Valid (Element) // 3.2.1 The element information item must have no // character or element information item [children]. // if (fNil) { if (childCount > 0 || !XMLString::equals(fDatatypeBuffer.getRawBuffer(), XMLUni::fgZeroLenString)) { emitError(XMLValid::NilAttrNotEmpty, elemDecl->getFullName()); fErrorOccurred = true; } } else { // Get the element's content model or fault it in XMLContentModel* elemCM = currType->getContentModel(); // Ask it to validate and return its return unsigned int emptyNS = getScanner()->getEmptyNamespaceId(); int result = elemCM->validateContent(children, childCount, emptyNS); if (result != -1) { result = elemCM->validateContentSpecial(children , childCount , emptyNS , fGrammarResolver , fGrammarResolver->getStringPool()); } if(result != -1) { fErrorOccurred = true; } return result; } } else if (modelType == SchemaElementDecl::Simple || modelType == SchemaElementDecl::Any) { // Normally for SchemaElementDecl::Any, We pass no judgement on it and anything goes // but if there is a fXsiTypeValidator, we need to use it for validation if (modelType == SchemaElementDecl::Simple && childCount > 0) { emitError(XMLValid::SimpleTypeHasChild, elemDecl->getFullName()); fErrorOccurred = true; } else if (fCurrentDatatypeValidator) { XMLCh* value = fDatatypeBuffer.getRawBuffer(); XMLCh* elemDefaultValue = ((SchemaElementDecl*) elemDecl)->getDefaultValue(); if (fNil) { if ((!XMLString::equals(value, XMLUni::fgZeroLenString)) || elemDefaultValue) { emitError(XMLValid::NilAttrNotEmpty, elemDecl->getFullName()); fErrorOccurred = true; } } else { DatatypeValidator::ValidatorType eleDefDVType = fCurrentDatatypeValidator->getType(); if (eleDefDVType == DatatypeValidator::NOTATION) { // if notation, need to bind URI to notation first if (!fNotationBuf) fNotationBuf = new (fMemoryManager) XMLBuffer(1023, fMemoryManager); // Make sure that this value maps to one of the // 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 Grammar is parsed), then obviously // this value will be legal since it matches one of them. int colonPos = -1; unsigned int uriId = getScanner()->resolveQName(value, *fNotationBuf, ElemStack::Mode_Element, colonPos); fNotationBuf->set(getScanner()->getURIText(uriId)); fNotationBuf->append(chColon); fNotationBuf->append(&value[colonPos + 1]); value = fNotationBuf->getRawBuffer(); } if (elemDefaultValue) { if (XMLString::equals(value, XMLUni::fgZeroLenString)) { fElemIsSpecified = true; // if this element didn't specified any value // use default value if (getScanner()->getDocHandler()) getScanner()->getDocHandler()->docCharacters(elemDefaultValue, XMLString::stringLen(elemDefaultValue), false); // Normally for default value, it has been validated already during TraverseSchema // But if there was a xsi:type and this validator is fXsiTypeValidator, // need to validate again // we determine this if the current content dataype validator // is neither the one in the element nor the one in the current // complex type (if any) if ((fCurrentDatatypeValidator != ((SchemaElementDecl*)elemDecl)->getDatatypeValidator()) && (!fTypeStack->peek() || (fCurrentDatatypeValidator != fTypeStack->peek()->getDatatypeValidator()))) value = elemDefaultValue; else value = 0; } else { // this element has specified some value // if the flag is FIXED, then this value must be same as default value if ((((SchemaElementDecl*)elemDecl)->getMiscFlags() & SchemaSymbols::XSD_FIXED) != 0) { if (fCurrentDatatypeValidator->compare(value, elemDefaultValue, fMemoryManager) != 0 ) { emitError(XMLValid::FixedDifferentFromActual, elemDecl->getFullName()); fErrorOccurred = true; } } } } else { // no default value, then check nillable if (XMLString::equals(value, XMLUni::fgZeroLenString) && (((SchemaElementDecl*)elemDecl)->getMiscFlags() & SchemaSymbols::XSD_NILLABLE) != 0) value = 0; } if ((!fErrorOccurred) && value) { try { fCurrentDatatypeValidator->validate(value, getScanner()->getValidationContext(), fMemoryManager); } catch (XMLException& idve) { emitError (XMLValid::DatatypeError, idve.getType(), idve.getMessage()); fErrorOccurred = true; } catch(const OutOfMemoryException&) { throw; } catch (...) { emitError(XMLValid::GenericError); throw; } } } } else if (modelType == SchemaElementDecl::Simple) { emitError(XMLValid::NoDatatypeValidatorForSimpleType, elemDecl->getFullName()); fErrorOccurred = true; } } else { ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMType, fMemoryManager); } // must rely on scanner to clear fDatatypeBuffer // since it may need to query its contents after this method completes fNil = false; fTrailing=false; fCurrentDatatypeValidator = 0; // Went ok, so return success return -1;}void SchemaValidator::faultInAttr (XMLAttr& toFill, const XMLAttDef& attDef) const{ // // At this level, we cannot set the URI id. So we just set it to zero // and leave it at that. The scanner, who called us, will look at the // prefix we stored (if any), resolve it, and store the URL id if any. // SchemaAttDef* schemaAttDef = (SchemaAttDef*) &attDef; QName* attName = schemaAttDef->getAttName(); toFill.set ( attName->getURI() , attName->getLocalPart() , attName->getPrefix() , schemaAttDef->getValue() , schemaAttDef->getType() );}void SchemaValidator::reset(){ fTrailing = false; fSeenId = false; fTypeStack->removeAllElements(); delete fXsiType; fXsiType = 0; fCurrentDatatypeValidator = 0; fNil = false; fDatatypeBuffer.reset(); fErrorOccurred = false;}bool SchemaValidator::requiresNamespaces() const{ return true;}void SchemaValidator::validateAttrValue (const XMLAttDef* attDef , const XMLCh* const attrValue , bool preValidation , const XMLElementDecl* elemDecl){ fErrorOccurred = false; //turn on IdRefList checking getScanner()->getValidationContext()->toCheckIdRefList(true); // // Get quick refs to lot of the stuff in the passed objects in // order to simplify the code below, which will reference them very // often. // XMLAttDef::AttTypes type = attDef->getType(); const XMLAttDef::DefAttTypes defType = attDef->getDefaultType(); // // If the default type is fixed, then make sure the passed value maps // to the fixed value. // // If during preContentValidation, the value we are validating is the fixed value itself // so no need to compare. // Only need to do this for regular attribute value validation // if ((defType == XMLAttDef::Fixed || defType == XMLAttDef::Required_And_Fixed) && !preValidation) { const XMLCh* const valueText = attDef->getValue(); if (!XMLString::equals(attrValue, valueText)) { emitError(XMLValid::NotSameAsFixedValue, attDef->getFullName(), attrValue, valueText); fErrorOccurred = true; } } // An empty string cannot be valid for non_CDATA any of the other types if (!attrValue[0] && type != XMLAttDef::Simple) { emitError(XMLValid::InvalidEmptyAttValue, attDef->getFullName()); // accords with original DOMTypeInfo implementation, but this does not feel right. fMostRecentAttrValidator = DatatypeValidatorFactory::getBuiltInRegistry()->get(SchemaSymbols::fgDT_ANYSIMPLETYPE); fErrorOccurred = true; return; } DatatypeValidator* attDefDV = ((SchemaAttDef*) attDef)->getDatatypeValidator(); if (!attDefDV) { emitError(XMLValid::NoDatatypeValidatorForAttribute, attDef->getFullName()); fErrorOccurred = true; } else { DatatypeValidator::ValidatorType attDefDVType = attDefDV->getType(); ValidationContext *context = getScanner()->getValidationContext(); try { // first, if notation, need to bind URI to notation first if (attDefDVType == DatatypeValidator::NOTATION) { // // Make sure that this value maps to one of the // 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 Grammar is parsed), then obviously // this value will be legal since it matches one of them. // XMLBuffer notationBuf(1023, fMemoryManager);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?