diff --git a/src/xercesc/internal/IGXMLScanner.cpp b/src/xercesc/internal/IGXMLScanner.cpp index d6022a5ce51244f23bf9df8f413d39d87c717a20..440951b306bff50557f916db6fb57b989daf6e7f 100644 --- a/src/xercesc/internal/IGXMLScanner.cpp +++ b/src/xercesc/internal/IGXMLScanner.cpp @@ -1653,6 +1653,9 @@ bool IGXMLScanner::scanStartTag(bool& gotData) // pairs until we get there. unsigned int attCount = 0; unsigned int curAttListSize = fAttrList->size(); + wasAdded = false; + fElemCount++; + while (true) { // And get the next non-space character @@ -1737,27 +1740,14 @@ bool IGXMLScanner::scanStartTag(bool& gotData) // See if this attribute is declared for this element. If we are // not validating of course it will not be at first, but we will // fault it into the pool (to avoid lots of redundant errors.) - wasAdded = false; - XMLAttDef* attDef = elemDecl->findAttr - ( - fAttNameBuf.getRawBuffer() - , 0 - , 0 - , 0 - , XMLElementDecl::AddIfNotFound - , wasAdded - ); - - if (wasAdded) + XMLCh * namePtr = fAttNameBuf.getRawBuffer(); + XMLAttDef* attDef = ((DTDElementDecl *)elemDecl)->getAttDef(namePtr); + if (!attDef) { // If there is a validation handler, then we are validating // so emit an error. if (fValidate) - { - // This is to tell the Validator that this attribute was - // faulted-in, was not an attribute in the attdef originally - attDef->setCreateReason(XMLAttDef::JustFaultIn); - + { fValidator->emitError ( XMLValid::AttNotDefinedForElement @@ -1765,45 +1755,52 @@ bool IGXMLScanner::scanStartTag(bool& gotData) , elemDecl->getFullName() ); } + unsigned int *curCountPtr = fUndeclaredAttrRegistry->get(namePtr); + if(!curCountPtr) + { + curCountPtr = getNewUIntPtr(); + *curCountPtr = fElemCount; + fUndeclaredAttrRegistry->put((void *)namePtr, curCountPtr); + } + else if(*curCountPtr < fElemCount) + *curCountPtr = fElemCount; + else + { + emitError + ( + XMLErrs::AttrAlreadyUsedInSTag + , namePtr + , elemDecl->getFullName() + ); + } } else { - // If this attribute was faulted-in and first occurence, - // then emit an error - if (fValidate && attDef->getCreateReason() == XMLAttDef::JustFaultIn - && !attDef->getProvided()) + // prepare for duplicate detection + unsigned int *curCountPtr = fAttDefRegistry->get(attDef); + if(!curCountPtr) { - fValidator->emitError - ( - XMLValid::AttNotDefinedForElement - , fAttNameBuf.getRawBuffer() + curCountPtr = getNewUIntPtr(); + *curCountPtr = fElemCount; + fAttDefRegistry->put(attDef, curCountPtr); + } + else if(*curCountPtr < fElemCount) + *curCountPtr = fElemCount; + else + { + emitError + ( + XMLErrs::AttrAlreadyUsedInSTag + , attDef->getFullName() , elemDecl->getFullName() ); } } - - // If its already provided, then there are more than one of - // this attribute in this start tag, so emit an error. - if (attDef->getProvided()) - { - emitError - ( - XMLErrs::AttrAlreadyUsedInSTag - , attDef->getFullName() - , elemDecl->getFullName() - ); - } - else - { - // Mark this one as already seen - attDef->setProvided(true); - } - // Skip any whitespace before the value and then scan the att // value. This will come back normalized with entity refs and // char refs expanded. fReaderMgr.skipPastSpaces(); - if (!scanAttValue(attDef, fAttValueBuf)) + if (!scanAttValue(attDef, namePtr, fAttValueBuf)) { static const XMLCh tmpList[] = { @@ -1841,7 +1838,7 @@ bool IGXMLScanner::scanStartTag(bool& gotData) // determine if it has a valid value. It will output any needed // errors, but we just keep going. We only need to do this if // we are validating. - if (!wasAdded && attDef->getCreateReason() != XMLAttDef::JustFaultIn) + if (attDef) { // Let the validator pass judgement on the attribute value if (fValidate) @@ -1865,10 +1862,10 @@ bool IGXMLScanner::scanStartTag(bool& gotData) curAtt = new (fMemoryManager) XMLAttr ( -1 - , fAttNameBuf.getRawBuffer() + , namePtr , XMLUni::fgZeroLenString , fAttValueBuf.getRawBuffer() - , attDef->getType() + , (attDef)?attDef->getType():XMLAttDef::CData , true , fMemoryManager ); @@ -1880,10 +1877,10 @@ bool IGXMLScanner::scanStartTag(bool& gotData) curAtt->set ( -1 - , fAttNameBuf.getRawBuffer() + , namePtr , XMLUni::fgZeroLenString , fAttValueBuf.getRawBuffer() - , attDef->getType() + , (attDef)?attDef->getType():XMLAttDef::CData ); curAtt->setSpecified(true); } @@ -1948,8 +1945,9 @@ bool IGXMLScanner::scanStartTag(bool& gotData) const XMLAttDef& curDef = attDefList.getAttDef(i); const XMLAttDef::DefAttTypes defType = curDef.getDefaultType(); - if (!curDef.getProvided()) - { + unsigned int *attCountPtr = fAttDefRegistry->get(&curDef); + if (!attCountPtr || *attCountPtr < fElemCount) + { // did not occur if (fValidate) { // If we are validating and its required, then an error @@ -2777,7 +2775,6 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData) ( eName->getLocalPart() , fURIStringPool->getValueForId(eName->getURI()) - , eName->getPrefix() , fPSVIAttrList ); } @@ -3348,7 +3345,6 @@ void IGXMLScanner::endElementPSVI(SchemaElementDecl* const elemDecl, ( elemDecl->getBaseName() , fURIStringPool->getValueForId(elemDecl->getURI()) - , elemDecl->getElementName()->getPrefix() , fPSVIElement ); diff --git a/src/xercesc/internal/IGXMLScanner.hpp b/src/xercesc/internal/IGXMLScanner.hpp index 28c045bce7805d76d8b5c0364b4ae8957e66d53a..a685300d71209e4043d91a8711cc215b95d87755 100644 --- a/src/xercesc/internal/IGXMLScanner.hpp +++ b/src/xercesc/internal/IGXMLScanner.hpp @@ -56,6 +56,11 @@ /* * $Log$ + * Revision 1.16 2003/11/28 05:13:29 neilg + * Fix state-ful duplicate attribute detection when the integrated + * scanner is in use and namespaces are off. Also, implement + * change to PSVIHandler interface to remove prefix passing. + * * Revision 1.15 2003/11/27 22:52:37 knoaman * PSVIElement implementation * @@ -285,6 +290,7 @@ private : bool scanAttValue ( const XMLAttDef* const attDef + , const XMLCh* const attrName , XMLBuffer& toFill ); bool scanContent(const bool extEntity); diff --git a/src/xercesc/internal/IGXMLScanner2.cpp b/src/xercesc/internal/IGXMLScanner2.cpp index 88d5e38a4541c619f4742e1837df0816a5be1511..3d39d594d59a39fa0635cfce22838c8067c92531 100644 --- a/src/xercesc/internal/IGXMLScanner2.cpp +++ b/src/xercesc/internal/IGXMLScanner2.cpp @@ -2152,6 +2152,7 @@ bool IGXMLScanner::basicAttrValueScan(const XMLCh* const attrName, XMLBuffer& to bool IGXMLScanner::scanAttValue( const XMLAttDef* const attDef + , const XMLCh* const attrName , XMLBuffer& toFill) { enum States @@ -2161,8 +2162,9 @@ bool IGXMLScanner::scanAttValue( const XMLAttDef* const attDef }; // Get the type and name - const XMLAttDef::AttTypes type = attDef->getType(); - const XMLCh* const attrName = attDef->getFullName(); + const XMLAttDef::AttTypes type = (attDef) + ?attDef->getType() + :XMLAttDef::CData; // Reset the target buffer toFill.reset(); @@ -2177,7 +2179,9 @@ bool IGXMLScanner::scanAttValue( const XMLAttDef* const attDef const unsigned int curReader = fReaderMgr.getCurrentReaderNum(); // Get attribute def - to check to see if it's declared externally or not - bool isAttExternal = attDef->isExternal(); + bool isAttExternal = (attDef) + ?attDef->isExternal() + :false; // Loop until we get the attribute value. Note that we use a double // loop here to avoid the setup/teardown overhead of the exception diff --git a/src/xercesc/internal/SGXMLScanner.cpp b/src/xercesc/internal/SGXMLScanner.cpp index f4d4226cfe78bcb5c886dbe249dfe600b6b80a45..bda90e8ab7c25ce5b81b818c9faf430271ba0acc 100644 --- a/src/xercesc/internal/SGXMLScanner.cpp +++ b/src/xercesc/internal/SGXMLScanner.cpp @@ -1730,7 +1730,6 @@ bool SGXMLScanner::scanStartTag(bool& gotData) ( eName->getLocalPart() , fURIStringPool->getValueForId(eName->getURI()) - , eName->getPrefix() , fPSVIAttrList ); } @@ -4773,7 +4772,6 @@ void SGXMLScanner::endElementPSVI(SchemaElementDecl* const elemDecl, ( elemDecl->getBaseName() , fURIStringPool->getValueForId(elemDecl->getURI()) - , elemDecl->getElementName()->getPrefix() , fPSVIElement );