dgxmlscanner.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,902 行 · 第 1/5 页

CPP
1,902
字号
        fValidator->validateElement(elemDecl);    }    // Expand the element stack and add the new element    fElemStack.addLevel(elemDecl, fReaderMgr.getCurrentReaderNum());    //  If this is the first element and we are validating, check the root    //  element.    if (isRoot)    {        fRootGrammar = fGrammar;        if (fValidate)        {            //  If a DocType exists, then check if it matches the root name there.            if (fRootElemName && !XMLString::equals(qnameRawBuf, fRootElemName))                fValidator->emitError(XMLValid::RootElemNotLikeDocType);            //  Some validators may also want to check the root, call the            //  XMLValidator::checkRootElement            if (fValidatorFromUser && !fValidator->checkRootElement(elemDecl->getId()))                fValidator->emitError(XMLValid::RootElemNotLikeDocType);        }    }    else if (fValidate)    {        //  If the element stack is not empty, then add this element as a        //  child of the previous top element. If its empty, this is the root        //  elem and is not the child of anything.        fElemStack.addChild(elemDecl->getElementName(), true);    }    // Skip any whitespace after the name    fReaderMgr.skipPastSpaces();    //  We loop until we either see a /> or >, handling attribute/value    //  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        XMLCh nextCh = fReaderMgr.peekNextChar();        //  If the next character is not a slash or closed angle bracket,        //  then it must be whitespace, since whitespace is required        //  between the end of the last attribute and the name of the next        //  one.        if (attCount)        {            if ((nextCh != chForwardSlash) && (nextCh != chCloseAngle))            {                if (fReaderMgr.getCurrentReader()->isWhitespace(nextCh))                {                    // Ok, skip by them and peek another char                    fReaderMgr.skipPastSpaces();                    nextCh = fReaderMgr.peekNextChar();                }                 else                {                    // Emit the error but keep on going                    emitError(XMLErrs::ExpectedWhitespace);                }            }        }        //  Ok, here we first check for any of the special case characters.        //  If its not one, then we do the normal case processing, which        //  assumes that we've hit an attribute value, Otherwise, we do all        //  the special case checks.        if (!fReaderMgr.getCurrentReader()->isSpecialStartTagChar(nextCh))        {            //  Assume its going to be an attribute, so get a name from            //  the input.            if (!fReaderMgr.getName(fAttNameBuf))            {                emitError(XMLErrs::ExpectedAttrName);                fReaderMgr.skipPastChar(chCloseAngle);                return false;            }            // And next must be an equal sign            if (!scanEq())            {                static const XMLCh tmpList[] =                {                    chSingleQuote, chDoubleQuote, chCloseAngle                    , chOpenAngle, chForwardSlash, chNull                };                emitError(XMLErrs::ExpectedEqSign);                //  Try to sync back up by skipping forward until we either                //  hit something meaningful.                const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);                if ((chFound == chCloseAngle) || (chFound == chForwardSlash))                {                    // Jump back to top for normal processing of these                    continue;                }                else if ((chFound == chSingleQuote)                      ||  (chFound == chDoubleQuote)                      ||  fReaderMgr.getCurrentReader()->isWhitespace(chFound))                {                    // Just fall through assuming that the value is to follow                }                else if (chFound == chOpenAngle)                {                    // Assume a malformed tag and that new one is starting                    emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());                    return false;                }                else                {                    // Something went really wrong                    return false;                }            }            //  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.)            XMLAttDef* attDef = ((DTDElementDecl *)elemDecl)->getAttDef ( fAttNameBuf.getRawBuffer());            XMLCh * namePtr = fAttNameBuf.getRawBuffer();            //  Add this attribute to the attribute list that we use to            //  pass them to the handler. We reuse its existing elements            //  but expand it as required.            // Note that we want to this first since this will            // make a copy of the namePtr; we can then make use of            // that copy in the hashtable lookup that checks            // for duplicates.  This will mean we may have to update            // the type of the XMLAttr later.            XMLAttr* curAtt;            if (attCount >= curAttListSize)            {                if (fDoNamespaces) {                    curAtt = new (fMemoryManager) XMLAttr                    (                        fEmptyNamespaceId                        , fAttNameBuf.getRawBuffer()                        , XMLUni::fgZeroLenString                        , (attDef)?attDef->getType():XMLAttDef::CData                        , true                        , fMemoryManager                    );                }                else                {                    curAtt = new (fMemoryManager) XMLAttr                    (                        -1                        , fAttNameBuf.getRawBuffer()                        , XMLUni::fgZeroLenString                        , XMLUni::fgZeroLenString                        , (attDef)?attDef->getType():XMLAttDef::CData                        , true                        , fMemoryManager                    );                }                fAttrList->addElement(curAtt);            }            else            {                curAtt = fAttrList->elementAt(attCount);                if (fDoNamespaces)                {                    curAtt->set                    (                        fEmptyNamespaceId                        , fAttNameBuf.getRawBuffer()                        , XMLUni::fgZeroLenString                        , (attDef)?attDef->getType():XMLAttDef::CData                    );                }                else                {                    curAtt->set                    (                        -1                        , fAttNameBuf.getRawBuffer()                        , XMLUni::fgZeroLenString                        , XMLUni::fgZeroLenString                        , (attDef)?attDef->getType():XMLAttDef::CData                    );                }                curAtt->setSpecified(true);            }            // reset namePtr so it refers to newly-allocated memory            namePtr = (XMLCh *)curAtt->getName();            // now need to prepare for duplicate detection            if(attDef)            {                unsigned int *curCountPtr = fAttDefRegistry->get(attDef);                if(!curCountPtr)                {                    curCountPtr = getNewUIntPtr();                    *curCountPtr = fElemCount;                    fAttDefRegistry->put(attDef, curCountPtr);                }                else if(*curCountPtr < fElemCount)                    *curCountPtr = fElemCount;                else                {                    emitError                    (                         XMLErrs::AttrAlreadyUsedInSTag                        , attDef->getFullName()                        , elemDecl->getFullName()                    );                }            }            else            {                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()                    );                }            }            if (fValidate)            {                if (!attDef)                {                    fValidator->emitError                    (                        XMLValid::AttNotDefinedForElement                        , fAttNameBuf.getRawBuffer()                        , qnameRawBuf                    );                }            }            //  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, fAttNameBuf.getRawBuffer(), fAttValueBuf))            {                static const XMLCh tmpList[] =                {                    chCloseAngle, chOpenAngle, chForwardSlash, chNull                };                emitError(XMLErrs::ExpectedAttrValue);                //  It failed, so lets try to get synced back up. We skip                //  forward until we find some whitespace or one of the                //  chars in our list.                const XMLCh chFound = fReaderMgr.skipUntilInOrWS(tmpList);                if ((chFound == chCloseAngle)                ||  (chFound == chForwardSlash)                ||  fReaderMgr.getCurrentReader()->isWhitespace(chFound))                {                    //  Just fall through and process this attribute, though                    //  the value will be "".                }                else if (chFound == chOpenAngle)                {                    // Assume a malformed tag and that new one is starting                    emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());                    return false;                }                else                {                    // Something went really wrong                    return false;                }            }            // must set the newly-minted value on the XMLAttr:            curAtt->setValue(fAttValueBuf.getRawBuffer());            //  Now that its all stretched out, lets look at its type and            //  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 (attDef)            {                // Let the validator pass judgement on the attribute value                if (fValidate)                {                    fValidator->validateAttrValue                    (                        attDef                        , fAttValueBuf.getRawBuffer()                        , false                        , elemDecl                    );                }            }            if (fDoNamespaces)            {                //  Make sure that the name is basically well formed for namespace                //  enabled rules. It either has no colons, or it has one which                //  is neither the first or last char.                const int colonFirst = XMLString::indexOf(fAttNameBuf.getRawBuffer(), chColon);                if (colonFirst != -1)                {                    const int colonLast = XMLString::lastIndexOf(fAttNameBuf.getRawBuffer(), chColon);                    if (colonFirst != colonLast)                    {                        emitError(XMLErrs::TooManyColonsInName);                        continue;                    }                    else if ((colonFirst == 0)                          ||  (colonLast == (int)fAttNameBuf.getLen() - 1))                    {                        emitError(XMLErrs::InvalidColonPos);                        continue;                    }                }            }            attCount++;            // And jump back to the top of the loop            continue;        }        //  It was some special case character so do all of the checks and        //  deal with it.        if (!nextCh)            ThrowXMLwithMemMgr(UnexpectedEOFException, XMLExcepts::Gen_UnexpectedEOF, fMemoryManager);        if (nextCh == chForwardSlash)        {            fReaderMgr.getNextChar();            isEmpty = true;            if (!fReaderMgr.skippedChar(chCloseAngle))                emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());            break;        }        else if (nextCh == chCloseAngle)        {            fReaderMgr.getNextChar();            break;        }        else if (nextCh == chOpenAngle)        {            //  Check for this one specially, since its going to be common            //  and it is kind of auto-recovering since we've already hit the            //  next open bracket, which is what we would have seeked to (and            //  skipped this whole tag.)            emitError(XMLErrs::UnterminatedStartTag, elemDecl->getFullName());            break;        }        else if ((nextCh == chSingleQuote) || (nextCh == chDoubleQuote))        {            //  Check for this one specially, which is probably a missing            //  attribute name, e.g. ="value". Just issue expected name            //  error and eat the quoted string, then jump back to the            //  top again.            emitError(XMLErrs::ExpectedAttrName);            fReaderMgr.getNextChar();            fReaderMgr.skipQuotedString(nextCh);            fReaderMgr.skipPastSpaces();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?