igxmlscanner2.cpp

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

CPP
1,601
字号
/* * Copyright 2002, 2003,2004 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: IGXMLScanner2.cpp,v 1.74 2004/09/29 19:23:32 knoaman Exp $ */// ---------------------------------------------------------------------------//  This file holds some of the grunt work methods of IGXMLScanner.cpp to keep//  it a little more readable.// ---------------------------------------------------------------------------// ---------------------------------------------------------------------------//  Includes// ---------------------------------------------------------------------------#include <xercesc/internal/IGXMLScanner.hpp>#include <xercesc/internal/EndOfEntityException.hpp>#include <xercesc/util/UnexpectedEOFException.hpp>#include <xercesc/util/XMLUri.hpp>#include <xercesc/framework/LocalFileInputSource.hpp>#include <xercesc/framework/URLInputSource.hpp>#include <xercesc/framework/XMLDocumentHandler.hpp>#include <xercesc/framework/XMLEntityHandler.hpp>#include <xercesc/framework/XMLPScanToken.hpp>#include <xercesc/framework/XMLRefInfo.hpp>#include <xercesc/framework/XMLGrammarPool.hpp>#include <xercesc/framework/psvi/PSVIAttributeList.hpp>#include <xercesc/framework/psvi/PSVIElement.hpp>#include <xercesc/validators/common/ContentLeafNameTypeVector.hpp>#include <xercesc/validators/DTD/DTDGrammar.hpp>#include <xercesc/validators/DTD/DTDValidator.hpp>#include <xercesc/validators/DTD/XMLDTDDescriptionImpl.hpp>#include <xercesc/validators/datatype/DatatypeValidator.hpp>#include <xercesc/validators/schema/XMLSchemaDescriptionImpl.hpp>#include <xercesc/validators/schema/SchemaGrammar.hpp>#include <xercesc/validators/schema/SchemaValidator.hpp>#include <xercesc/validators/schema/TraverseSchema.hpp>#include <xercesc/validators/schema/SubstitutionGroupComparator.hpp>#include <xercesc/validators/schema/XSDDOMParser.hpp>#include <xercesc/validators/schema/identity/IdentityConstraintHandler.hpp>XERCES_CPP_NAMESPACE_BEGINinline XMLAttDefList& getAttDefList(bool              isSchemaGrammar                                  , ComplexTypeInfo*  currType                                  , XMLElementDecl*   elemDecl);// ---------------------------------------------------------------------------//  IGXMLScanner: Private helper methods// ---------------------------------------------------------------------------//  This method is called from scanStartTagNS() to build up the list of//  XMLAttr objects that will be passed out in the start tag callout. We//  get the key/value pairs from the raw scan of explicitly provided attrs,//  which have not been normalized. And we get the element declaration from//  which we will get any defaulted or fixed attribute defs and add those//  in as well.unsigned intIGXMLScanner::buildAttList(const  RefVectorOf<KVStringPair>&  providedAttrs                          , const unsigned int                attCount                          ,       XMLElementDecl*             elemDecl                          ,       RefVectorOf<XMLAttr>&       toFill){    //  If doing DTD's, Ask the element to clear the 'provided' flag on all of the att defs    //  that it owns, and to return us a boolean indicating whether it has    //  any defs.  If schemas are being validated, the complexType    // at the top of the SchemaValidator's stack will    // know what's best.  REVISIT:  don't modify grammar at all; eliminate    // this step...    ComplexTypeInfo *currType = 0;    DatatypeValidator *currDV = 0;    if(fGrammar->getGrammarType() == Grammar::SchemaGrammarType && fValidate)    {        currType = ((SchemaValidator*)fValidator)->getCurrentTypeInfo();        if (!currType) {            currDV = ((SchemaValidator*)fValidator)->getCurrentDatatypeValidator();        }    }    const bool hasDefs = (currType && fValidate)            ? currType->resetDefs()            : elemDecl->resetDefs();    // another set of attributes; increment element counter    fElemCount++;    //  If there are no expliclitily provided attributes and there are no    //  defined attributes for the element, the we don't have anything to do.    //  So just return zero in this case.    if (!hasDefs && !attCount)        return 0;    // Keep up with how many attrs we end up with total    unsigned int retCount = 0;    //  And get the current size of the output vector. This lets us use    //  existing elements until we fill it, then start adding new ones.    const unsigned int curAttListSize = toFill.size();    //  We need a buffer into which raw scanned attribute values will be    //  normalized.    XMLBufBid bbNormal(&fBufMgr);    XMLBuffer& normBuf = bbNormal.getBuffer();    //    // Decide if to use hash table to do duplicate checking    //    bool toUseHashTable = false;    if (fGrammarType == Grammar::DTDGrammarType)    {        setAttrDupChkRegistry(attCount, toUseHashTable);    }    //  Loop through our explicitly provided attributes, which are in the raw    //  scanned form, and build up XMLAttr objects.    unsigned int index;    for (index = 0; index < attCount; index++)    {        PSVIItem::VALIDITY_STATE attrValid = PSVIItem::VALIDITY_VALID;        PSVIItem::ASSESSMENT_TYPE attrAssessed = PSVIItem::VALIDATION_FULL;        const KVStringPair* curPair = providedAttrs.elementAt(index);        //  We have to split the name into its prefix and name parts. Then        //  we map the prefix to its URI.        const XMLCh* const namePtr = curPair->getKey();        ArrayJanitor<XMLCh> janName(0);        // use a stack-based buffer when possible.        XMLCh tempBuffer[100];        const int colonInd = XMLString::indexOf(namePtr, chColon);        const XMLCh* prefPtr = XMLUni::fgZeroLenString;        const XMLCh* suffPtr = XMLUni::fgZeroLenString;        if (colonInd != -1)        {            // We have to split the string, so make a copy.            if (XMLString::stringLen(namePtr) < sizeof(tempBuffer) / sizeof(tempBuffer[0]))            {                XMLString::copyString(tempBuffer, namePtr);                tempBuffer[colonInd] = chNull;                prefPtr = tempBuffer;            }            else            {                janName.reset(XMLString::replicate(namePtr, fMemoryManager), fMemoryManager);                janName[colonInd] = chNull;                prefPtr = janName.get();            }            suffPtr = namePtr + colonInd + 1;        }        else        {            // No colon, so we just have a name with no prefix            suffPtr = namePtr;        }        //  Map the prefix to a URI id. We tell him that we are mapping an        //  attr prefix, so any xmlns attrs at this level will not affect it.        const unsigned int uriId = resolvePrefix(prefPtr, ElemStack::Mode_Attribute);        //  If the uri comes back as the xmlns or xml URI or its just a name        //  and that name is 'xmlns', then we handle it specially. So set a        //  boolean flag that lets us quickly below know which we are dealing        //  with.        const bool isNSAttr = (uriId == fXMLNSNamespaceId)                              || (uriId == fXMLNamespaceId)                              || XMLString::equals(suffPtr, XMLUni::fgXMLNSString)                              || XMLString::equals(getURIText(uriId), SchemaSymbols::fgURI_XSI);        //  If its not a special case namespace attr of some sort, then we        //  do normal checking and processing.        XMLAttDef::AttTypes attType;        DatatypeValidator *attrValidator = 0;        PSVIAttribute *psviAttr = 0;        if (!isNSAttr || fGrammarType == Grammar::DTDGrammarType)        {            // Some checking for attribute wild card first (for schema)            bool laxThisOne = false;            bool skipThisOne = false;            XMLAttDef* attDefForWildCard = 0;            XMLAttDef*  attDef = 0;            if (fGrammarType == Grammar::SchemaGrammarType) {                //retrieve the att def                SchemaAttDef* attWildCard = 0;                if (currType) {                    attDef = currType->getAttDef(suffPtr, uriId);                    attWildCard = currType->getAttWildCard();                }                else if (!currDV) { // check explicitly-set wildcard                    attWildCard = ((SchemaElementDecl*)elemDecl)->getAttWildCard();                }                // if not found or faulted in - check for a matching wildcard attribute                // if no matching wildcard attribute, check (un)qualifed cases and flag                // appropriate errors                if (!attDef || (attDef->getCreateReason() == XMLAttDef::JustFaultIn)) {                    if (attWildCard) {                        //if schema, see if we should lax or skip the validation of this attribute                        if (anyAttributeValidation(attWildCard, uriId, skipThisOne, laxThisOne)) {                            if(!skipThisOne)                            {                                SchemaGrammar* sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(getURIText(uriId));                                if (sGrammar && sGrammar->getGrammarType() == Grammar::SchemaGrammarType) {                                    RefHashTableOf<XMLAttDef>* attRegistry = sGrammar->getAttributeDeclRegistry();                                    if (attRegistry) {                                        attDefForWildCard = attRegistry->get(suffPtr);                                    }                                }                            }                        }                    }                    else if (currType) {                        // not found, see if the attDef should be qualified or not                        if (uriId == fEmptyNamespaceId) {                            attDef = currType->getAttDef(suffPtr                                            , fURIStringPool->getId(fGrammar->getTargetNamespace()));                            if (fValidate                                && attDef                                && attDef->getCreateReason() != XMLAttDef::JustFaultIn) {                                // the attribute should be qualified                                fValidator->emitError                                (                                    XMLValid::AttributeNotQualified                                    , attDef->getFullName()                                );                                if(fGrammarType == Grammar::SchemaGrammarType) {                                    fPSVIElemContext.fErrorOccurred = true;                                    if (getPSVIHandler())                                    {                                        attrValid = PSVIItem::VALIDITY_INVALID;                                    }                                                                }                            }                        }                        else {                            attDef = currType->getAttDef(suffPtr                                            , fEmptyNamespaceId);                            if (fValidate                                && attDef                                && attDef->getCreateReason() != XMLAttDef::JustFaultIn) {                                // the attribute should be qualified                                fValidator->emitError                                (                                    XMLValid::AttributeNotUnQualified                                    , attDef->getFullName()                                );                                if(fGrammarType == Grammar::SchemaGrammarType) {                                    fPSVIElemContext.fErrorOccurred = true;                                    if (getPSVIHandler())                                    {                                        attrValid = PSVIItem::VALIDITY_INVALID;                                    }                                }                            }                        }                    }                }            }            //  Find this attribute within the parent element. We pass both            //  the uriID/name and the raw QName buffer, since we don't know            //  how the derived validator and its elements store attributes.            else            {                if(fGrammarType == Grammar::DTDGrammarType)                     attDef = ((DTDElementDecl *)elemDecl)->getAttDef ( namePtr);            }             // 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()                    );                    fPSVIElemContext.fErrorOccurred = true;                }            }            else            {                if(fGrammarType == Grammar::DTDGrammarType)                 {                    unsigned int *curCountPtr = fUndeclaredAttrRegistry->get(namePtr);                    if(!curCountPtr)                    {                        curCountPtr = getNewUIntPtr();

⌨️ 快捷键说明

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