Erik,
Opps one second, should have thought more before hitting the reply ....
Reusing Grammar means reusing all the element decl/attribute decl stored during
the earlier DTD scanned. So the root element should also be reused. Thus if
the root element changes between the scans which doesn't not match the stored
one, it is correct behaviour for the parser to issue a mismatch error message.
So the parser works as design. We shouldn't need to store the root id again.
Tinny
Erik Rydgren wrote:
> Hi!
>
> If the validator is reused and the root element changes between the scans
> then there is a bug in DTDScanner::scanDocTypeDecl that causes a root
> element mismatch error that doesn't exist.
> The code in the nightly build 2001-04-20 looks like this.
>
> //
> // This element obviously is not going to exist in the element decl
> // pool yet, but we need to store away an element id. So force it into
> // the element decl pool, marked as being there because it was in
> // the DOCTYPE. Later, when its declared, the status will be updated.
> //
> // Only do this if we are not reusing the validator! If we are reusing,
> // then look it up instead. It has to exist!
> //
> DTDElementDecl* rootDecl;
> if (reuseGrammar)
> {
> rootDecl = (DTDElementDecl*)
> fDTDGrammar->getElemDecl(fEmptyNamespaceId, 0, bbRootName.getRawBuffer(),
> 0);
> if (fScanner->getDoValidation())
> {
> if (!rootDecl)
> {
>
> fScanner->getValidator()->emitError(XMLValid::UndeclaredElemInDocType,
> bbRootName.getRawBuffer());
> fReaderMgr->skipPastChar(chCloseAngle);
> return;
> }
> }
> }
> else
> {
> rootDecl = new DTDElementDecl(bbRootName.getRawBuffer(),
> fEmptyNamespaceId);
> rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
> fDTDGrammar->setRootElemId(fDTDGrammar->putElemDecl(rootDecl));
> }
>
> If reuse grammar is true then the right declaration is found and validated
> correctly, but since the Id is not remembered the validator will trow a root
> element mismatch error later. The code should look like this.
>
> //
> // This element obviously is not going to exist in the element decl
> // pool yet, but we need to store away an element id. So force it into
> // the element decl pool, marked as being there because it was in
> // the DOCTYPE. Later, when its declared, the status will be updated.
> //
> // Only do this if we are not reusing the validator! If we are reusing,
> // then look it up instead. It has to exist!
> //
> DTDElementDecl* rootDecl;
> if (reuseGrammar)
> {
> rootDecl = (DTDElementDecl*)
> fDTDGrammar->getElemDecl(fEmptyNamespaceId, 0, bbRootName.getRawBuffer(),
> 0);
> if (fScanner->getDoValidation())
> {
> if (!rootDecl)
> {
>
> fScanner->getValidator()->emitError(XMLValid::UndeclaredElemInDocType,
> bbRootName.getRawBuffer());
> fReaderMgr->skipPastChar(chCloseAngle);
> return;
> }
> }
> fDTDGrammar->setRootElemId(rootDecl->getId());
> }
> else
> {
> rootDecl = new DTDElementDecl(bbRootName.getRawBuffer(),
> fEmptyNamespaceId);
> rootDecl->setCreateReason(DTDElementDecl::AsRootElem);
> fDTDGrammar->setRootElemId(fDTDGrammar->putElemDecl(rootDecl));
> }
>
> I have made the change here and it works like a charm.
> I'm glad to be able to give something back.
>
> Regards
> Erik Rydgren
> Mandarinen systems AB
> Sweden
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]