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]

Reply via email to