tng 2002/11/07 13:57:37 Modified: c/src/xercesc/validators/schema SchemaValidator.cpp SchemaValidator.hpp Log: Fix the following Schema Test Failures: 1. Typo when comparing miscFlags with FIXED 2. If xsi:type is specified, need to validate using that xsitype validator even if the type was any 3. Need to check ID/IDREFs for element value 4. Need to duplicate attribute id for wildcard scenario. Revision Changes Path 1.18 +119 -17 xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.cpp Index: SchemaValidator.cpp =================================================================== RCS file: /home/cvs/xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.cpp,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- SchemaValidator.cpp 4 Nov 2002 14:49:42 -0000 1.17 +++ SchemaValidator.cpp 7 Nov 2002 21:57:37 -0000 1.18 @@ -56,6 +56,13 @@ /* * $Log$ + * Revision 1.18 2002/11/07 21:57:37 tng + * Fix the following Schema Test Failures: + * 1. Typo when comparing miscFlags with FIXED + * 2. If xsi:type is specified, need to validate using that xsitype validator even if the type was any + * 3. Need to check ID/IDREFs for element value + * 4. Need to duplicate attribute id for wildcard scenario. + * * Revision 1.17 2002/11/04 14:49:42 tng * C++ Namespace Support. * @@ -221,6 +228,7 @@ , fGrammarResolver(0) , fSchemaGrammar(0) , fTrailing(false) + , fSeenId(false) , fXsiType(0) , fXsiTypeValidator(0) , fNil(false) @@ -266,10 +274,6 @@ if (childCount) return 0; } - else if (modelType == SchemaElementDecl::Any) - { - // We pass no judgement on this one, anything goes - } else if ((modelType == SchemaElementDecl::Mixed_Simple) || (modelType == SchemaElementDecl::Mixed_Complex) || (modelType == SchemaElementDecl::Children)) @@ -301,24 +305,94 @@ return result; } } - else if (modelType == SchemaElementDecl::Simple) + else if (modelType == SchemaElementDecl::Simple || modelType == SchemaElementDecl::Any) { - if (childCount > 0) { + // 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()); } else { try { - DatatypeValidator* fCurrentDV = ((SchemaElementDecl*)elemDecl)->getDatatypeValidator(); + DatatypeValidator* fCurrentDV = 0; + bool hasXsiType = false; + + if (modelType == SchemaElementDecl::Simple) + fCurrentDV = ((SchemaElementDecl*)elemDecl)->getDatatypeValidator(); + // If there is xsi:type validator, substitute it. if (fXsiTypeValidator) { + hasXsiType = true; fCurrentDV = fXsiTypeValidator; fXsiTypeValidator = 0; } if (!fCurrentDV) { - emitError(XMLValid::NoDatatypeValidatorForSimpleType, elemDecl->getFullName()); + if (modelType == SchemaElementDecl::Simple) + emitError(XMLValid::NoDatatypeValidatorForSimpleType, elemDecl->getFullName()); } else { XMLCh* value = fDatatypeBuffer.getRawBuffer(); XMLCh* elemDefaultValue = ((SchemaElementDecl*) elemDecl)->getDefaultValue(); + DatatypeValidator::ValidatorType eleDefDVType = fCurrentDV->getType(); + + // if notation, need to bind URI to notation first + XMLBuffer notationBuf; + + // set up the entitydeclpool in ENTITYDatatypeValidator + // and the idreflist in ID/IDREFDatatypeValidator + + if (eleDefDVType == DatatypeValidator::List) { + DatatypeValidator* itemDTV = ((ListDatatypeValidator*)fCurrentDV)->getItemTypeDTV(); + DatatypeValidator::ValidatorType itemDTVType = itemDTV->getType(); + if (itemDTVType == DatatypeValidator::ENTITY) + ((ENTITYDatatypeValidator*)itemDTV)->setEntityDeclPool(getScanner()->getEntityDeclPool()); + else if (itemDTVType == DatatypeValidator::ID) + ((IDDatatypeValidator*)itemDTV)->setIDRefList(getScanner()->getIDRefList()); + else if (itemDTVType == DatatypeValidator::IDREF) { + ((IDREFDatatypeValidator*)itemDTV)->setIDRefList(getScanner()->getIDRefList()); + } + } + else if (eleDefDVType == DatatypeValidator::Union) { + RefVectorOf<DatatypeValidator>* memberDTV = ((UnionDatatypeValidator*)fCurrentDV)->getMemberTypeValidators(); + unsigned int memberTypeNumber = memberDTV->size(); + for ( unsigned int memberIndex = 0; memberIndex < memberTypeNumber; ++memberIndex) + { + DatatypeValidator::ValidatorType memberDTVType = memberDTV->elementAt(memberIndex)->getType(); + if (memberDTVType == DatatypeValidator::ENTITY) + ((ENTITYDatatypeValidator*)memberDTV->elementAt(memberIndex))->setEntityDeclPool(getScanner()->getEntityDeclPool()); + else if (memberDTVType == DatatypeValidator::ID) + ((IDDatatypeValidator*)memberDTV->elementAt(memberIndex))->setIDRefList(getScanner()->getIDRefList()); + else if (memberDTVType == DatatypeValidator::IDREF) { + ((IDREFDatatypeValidator*)memberDTV->elementAt(memberIndex))->setIDRefList(getScanner()->getIDRefList()); + } + } + } + else if (eleDefDVType == DatatypeValidator::ENTITY) + ((ENTITYDatatypeValidator*)fCurrentDV)->setEntityDeclPool(getScanner()->getEntityDeclPool()); + else if (eleDefDVType == DatatypeValidator::ID) + ((IDDatatypeValidator*)fCurrentDV)->setIDRefList(getScanner()->getIDRefList()); + else if (eleDefDVType == DatatypeValidator::IDREF) { + ((IDREFDatatypeValidator*)fCurrentDV)->setIDRefList(getScanner()->getIDRefList()); + } + else if (eleDefDVType == 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 nameBuf(XMLString::stringLen(value)+1); + XMLBuffer prefixBuf(XMLString::stringLen(value)+1); + unsigned int uriId = getScanner()->resolveQName(value, nameBuf, prefixBuf, ElemStack::Mode_Element); + notationBuf.set(getScanner()->getURIText(uriId)); + notationBuf.append(chColon); + notationBuf.append(nameBuf.getRawBuffer()); + value = notationBuf.getRawBuffer(); + } + if (elemDefaultValue) { // a default value was specified @@ -331,11 +405,18 @@ // 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 + if (hasXsiType) + fCurrentDV->validate(elemDefaultValue); + } 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::FIXED) != 0) { + if ((((SchemaElementDecl*)elemDecl)->getMiscFlags() & SchemaSymbols::FIXED) != 0) { if (fCurrentDV->compare(value, elemDefaultValue) != 0 ) emitError(XMLValid::FixedDifferentFromActual, elemDecl->getFullName()); } @@ -344,7 +425,7 @@ if (fNil) emitError(XMLValid::NilAttrNotEmpty, elemDecl->getFullName()); else - fCurrentDV->validate(value); + fCurrentDV->validate(value); } } else { @@ -408,6 +489,7 @@ void SchemaValidator::reset() { fTrailing = false; + fSeenId = false; delete fXsiType; fXsiType = 0; fXsiTypeValidator = 0; @@ -420,9 +502,10 @@ return true; } -void SchemaValidator::validateAttrValue (const XMLAttDef* attDef - , const XMLCh* const attrValue - , bool preValidation) +void SchemaValidator::validateAttrValue (const XMLAttDef* attDef + , const XMLCh* const attrValue + , bool preValidation + , const XMLElementDecl* elemDecl) { // // Get quick refs to lot of the stuff in the passed objects in @@ -466,13 +549,18 @@ // 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::ENTITY) ((ENTITYDatatypeValidator*)itemDTV)->setEntityDeclPool(getScanner()->getEntityDeclPool()); - else if (itemDTVType == DatatypeValidator::ID) + else if (itemDTVType == DatatypeValidator::ID) { ((IDDatatypeValidator*)itemDTV)->setIDRefList(getScanner()->getIDRefList()); + thisIsAnId = true; + } else if (itemDTVType == DatatypeValidator::IDREF) { // if in prevalidatoin, do not add attDef to IDREFList if (preValidation) @@ -489,8 +577,10 @@ DatatypeValidator::ValidatorType memberDTVType = memberDTV->elementAt(memberIndex)->getType(); if (memberDTVType == DatatypeValidator::ENTITY) ((ENTITYDatatypeValidator*)memberDTV->elementAt(memberIndex))->setEntityDeclPool(getScanner()->getEntityDeclPool()); - else if (memberDTVType == DatatypeValidator::ID) + else if (memberDTVType == DatatypeValidator::ID) { ((IDDatatypeValidator*)memberDTV->elementAt(memberIndex))->setIDRefList(getScanner()->getIDRefList()); + thisIsAnId = true; + } else if (memberDTVType == DatatypeValidator::IDREF) { // if in prevalidatoin, do not add attDef to IDREFList if (preValidation) @@ -502,8 +592,10 @@ } else if (attDefDVType == DatatypeValidator::ENTITY) ((ENTITYDatatypeValidator*)attDefDV)->setEntityDeclPool(getScanner()->getEntityDeclPool()); - else if (attDefDVType == DatatypeValidator::ID) + else if (attDefDVType == DatatypeValidator::ID) { ((IDDatatypeValidator*)attDefDV)->setIDRefList(getScanner()->getIDRefList()); + thisIsAnId = true; + } else if (attDefDVType == DatatypeValidator::IDREF) { // if in prevalidatoin, do not add attDef to IDREFList if (preValidation) @@ -534,8 +626,20 @@ attDefDV->validate(notationBuf.getRawBuffer()); } - else + else { + if (thisIsAnId) { + if (fSeenId) + emitError + ( + XMLValid::MultipleIdAttrs + , elemDecl->getFullName() + ); + else + fSeenId = true; + } attDefDV->validate(attrValue); + } + } catch (InvalidDatatypeValueException& idve) { emitError (XMLValid::DatatypeError, idve.getType(), idve.getMessage()); } @@ -721,6 +825,7 @@ fDatatypeBuffer.reset(); fTrailing = false; + fSeenId = false; } void SchemaValidator::preContentValidation(bool reuseGrammar, @@ -879,6 +984,7 @@ &curAttDef , curAttDef.getValue() , true + , &curElem ); } } 1.10 +8 -0 xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.hpp Index: SchemaValidator.hpp =================================================================== RCS file: /home/cvs/xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.hpp,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- SchemaValidator.hpp 4 Nov 2002 14:49:42 -0000 1.9 +++ SchemaValidator.hpp 7 Nov 2002 21:57:37 -0000 1.10 @@ -56,6 +56,13 @@ /* * $Log$ + * Revision 1.10 2002/11/07 21:57:37 tng + * Fix the following Schema Test Failures: + * 1. Typo when comparing miscFlags with FIXED + * 2. If xsi:type is specified, need to validate using that xsitype validator even if the type was any + * 3. Need to check ID/IDREFs for element value + * 4. Need to duplicate attribute id for wildcard scenario. + * * Revision 1.9 2002/11/04 14:49:42 tng * C++ Namespace Support. * @@ -191,6 +198,7 @@ const XMLAttDef* attDef , const XMLCh* const attrValue , bool preValidation = false + , const XMLElementDecl* elemDecl = 0 ); virtual void validateElement @@ -335,6 +343,9 @@ // fTrailing // Previous chunk had a trailing space // + // fSeenId + // Indicate if an attribute of ID type has been seen already, reset per element. + // // fSchemaErrorReporter // Report schema process errors // @@ -350,6 +361,7 @@ XMLBuffer fDatatypeBuffer; bool fTrailing; + bool fSeenId; XSDErrorReporter fSchemaErrorReporter; ValueStackOf<ComplexTypeInfo*>* fTypeStack; };
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]