traverseschema.cpp

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

CPP
1,791
字号
    {        left = new (fGrammarPoolMemoryManager) ContentSpecNode        (            ((ContentSpecNode::NodeTypes) modelGroupType) == ContentSpecNode::Choice                ? ContentSpecNode::ModelGroupChoice : ContentSpecNode::ModelGroupSequence            , left            , right            , true            , true            , fGrammarPoolMemoryManager        );        if (!janAnnot.isDataNull())            fSchemaGrammar->putAnnotation(left, janAnnot.release());    }    return left;}/**  * Traverse SimpleType declaration:  * <simpleType  *     id = ID  *     name = NCName>  *     Content: (annotation? , ((list | restriction | union)))  * </simpleType>  *  * traverse <list>|<restriction>|<union>  */DatatypeValidator*TraverseSchema::traverseSimpleTypeDecl(const DOMElement* const childElem,                                       const bool topLevel, int baseRefContext){    // ------------------------------------------------------------------    // Process contents    // ------------------------------------------------------------------    const XMLCh* name = getElementAttValue(childElem,SchemaSymbols::fgATT_NAME);    bool nameEmpty = (!name || !*name);    if (topLevel && nameEmpty) {        reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,                          SchemaSymbols::fgELT_SIMPLETYPE);        return 0;    }    if (nameEmpty) { // anonymous simpleType        name = genAnonTypeName(fgAnonSNamePrefix);    }    else if (!XMLString::isValidNCName(name)) {        reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,                          SchemaSymbols::fgELT_SIMPLETYPE, name);        return 0;    }    fBuffer.set(fTargetNSURIString);    fBuffer.append(chComma);    fBuffer.append(name);    unsigned int fullTypeNameId = fStringPool->addOrFind(fBuffer.getRawBuffer());    const XMLCh* fullName = fStringPool->getValueForId(fullTypeNameId);    //check if we have already traversed the same simpleType decl    DatatypeValidator* dv = fDatatypeRegistry->getDatatypeValidator(fullName);    if (!dv) {        // -------------------------------------------------------------------        // Check attributes        // -------------------------------------------------------------------        unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_SimpleTypeGlobal                                          : GeneralAttributeCheck::E_SimpleTypeLocal;        fAttributeCheck.checkAttributes(            childElem, scope, this, topLevel, fNonXSAttList        );        // Circular constraint checking        if (fCurrentTypeNameStack->containsElement(fullTypeNameId)) {            reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, name);            return 0;        }        fCurrentTypeNameStack->addElement(fullTypeNameId);        // Get 'final' values        int finalSet = parseFinalSet(childElem, S_Final);        // annotation?,(list|restriction|union)        DOMElement* content= checkContent(            childElem, XUtil::getFirstChildElement(childElem), false);                if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size())        {            fAnnotation = generateSyntheticAnnotation(childElem, fNonXSAttList);                }        Janitor<XSAnnotation> janAnnot(fAnnotation);        if (content == 0) {            reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::EmptySimpleTypeContent);            popCurrentTypeNameStack();            return 0;        }        const XMLCh* varietyName = content->getLocalName();        // Remark: some code will be repeated in list|restriction| union but it        //         is cleaner that way        if (XMLString::equals(varietyName, SchemaSymbols::fgELT_LIST)) { //traverse List            if ((baseRefContext & SchemaSymbols::XSD_LIST) != 0) {                reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AtomicItemType);                popCurrentTypeNameStack();                return 0;            }            dv = traverseByList(childElem, content, name, fullName, finalSet, &janAnnot);        }        else if (XMLString::equals(varietyName, SchemaSymbols::fgELT_RESTRICTION)) { //traverse Restriction            dv = traverseByRestriction(childElem, content, name, fullName, finalSet, &janAnnot);        }        else if (XMLString::equals(varietyName, SchemaSymbols::fgELT_UNION)) { //traverse union            dv = traverseByUnion(childElem, content, name, fullName, finalSet, baseRefContext, &janAnnot);        }        else {            reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::FeatureUnsupported, varietyName);            popCurrentTypeNameStack();        }        if (dv) {            if (nameEmpty)                dv->setAnonymous();            if (!janAnnot.isDataNull())                fSchemaGrammar->putAnnotation(dv, janAnnot.release());        }    }    return dv;}/**  * Traverse ComplexType Declaration - CR Implementation.  *  *     <complexType  *        abstract = boolean  *        block = #all or (possibly empty) subset of {extension, restriction}  *        final = #all or (possibly empty) subset of {extension, restriction}  *        id = ID  *        mixed = boolean : false  *        name = NCName>  *        Content: (annotation? , (simpleContent | complexContent |  *                   ( (group | all | choice | sequence)? ,  *                   ( (attribute | attributeGroup)* , anyAttribute?))))  *     </complexType>  */int TraverseSchema::traverseComplexTypeDecl(const DOMElement* const elem,                                            const bool topLevel,                                            const XMLCh* const recursingTypeName) {    // Get the attributes of the complexType    const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);    bool isAnonymous = false;    if (!name || !*name) {        if (topLevel) {            reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TopLevelNoNameComplexType);            return -1;        }        if (recursingTypeName)            name = recursingTypeName;        else {            name = genAnonTypeName(fgAnonCNamePrefix);            isAnonymous = true;        }    }    if (!XMLString::isValidNCName(name)) {        //REVISIT - Should we return or continue and save type with wrong name?        reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,                          SchemaSymbols::fgELT_COMPLEXTYPE, name);        return -1;    }    // ------------------------------------------------------------------    // Check if the type has already been registered    // ------------------------------------------------------------------    fBuffer.set(fTargetNSURIString);    fBuffer.append(chComma);    fBuffer.append(name);    int typeNameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());    const XMLCh* fullName = fStringPool->getValueForId(typeNameIndex);    ComplexTypeInfo* typeInfo = 0;    if (topLevel || recursingTypeName) {        typeInfo = fComplexTypeRegistry->get(fullName);        if (typeInfo && !typeInfo->getPreprocessed()) {            return typeNameIndex;        }    }    // -----------------------------------------------------------------------    // Check Attributes    // -----------------------------------------------------------------------    unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_ComplexTypeGlobal                                      : GeneralAttributeCheck::E_ComplexTypeLocal;    fAttributeCheck.checkAttributes(elem, scope, this, topLevel, fNonXSAttList);    // -----------------------------------------------------------------------    // Create a new instance    // -----------------------------------------------------------------------    bool preProcessFlag = (typeInfo) ? typeInfo->getPreprocessed() : false;    unsigned int previousCircularCheckIndex = fCircularCheckIndex;    int previousScope = fCurrentScope;    if (preProcessFlag) {        fCurrentScope = typeInfo->getScopeDefined();        typeInfo->setPreprocessed(false);    }    else {        // ------------------------------------------------------------------        // Register the type        // ------------------------------------------------------------------        typeInfo = new (fGrammarPoolMemoryManager) ComplexTypeInfo(fGrammarPoolMemoryManager);        if(isAnonymous) {            typeInfo->setAnonymous();        }        fCurrentScope = fScopeCount++;        fComplexTypeRegistry->put((void*) fullName, typeInfo);        typeInfo->setTypeName(fullName);        typeInfo->setScopeDefined(fCurrentScope);        if (fFullConstraintChecking) {            XSDLocator* aLocator = new (fGrammarPoolMemoryManager) XSDLocator();            aLocator->setValues(fStringPool->getValueForId(fStringPool->addOrFind(fSchemaInfo->getCurrentSchemaURL())),                                0, ((XSDElementNSImpl*) elem)->getLineNo(),                                ((XSDElementNSImpl*) elem)->getColumnNo());            typeInfo->setLocator(aLocator);        }    }    fCurrentTypeNameStack->addElement(typeNameIndex);    ComplexTypeInfo* saveTypeInfo = fCurrentComplexType;    fCurrentComplexType = typeInfo;    // ------------------------------------------------------------------    // First, handle any ANNOTATION declaration and get next child    // ------------------------------------------------------------------    DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true);        if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size())    {        fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList);            }    Janitor<XSAnnotation> janAnnot(fAnnotation);    // ------------------------------------------------------------------    // Process the content of the complex type declaration    // ------------------------------------------------------------------    try {        const XMLCh* mixedVal = getElementAttValue(elem,SchemaSymbols::fgATT_MIXED);        bool isMixed = false;        if ((mixedVal && *mixedVal)            && (XMLString::equals(SchemaSymbols::fgATTVAL_TRUE, mixedVal)                || XMLString::equals(fgValueOne, mixedVal))) {            isMixed = true;        }        if (child == 0) {            // EMPTY complexType with complexContent            processComplexContent(elem, name, child, typeInfo, 0, isMixed);        }        else {            const XMLCh* childName = child->getLocalName();            if (XMLString::equals(childName, SchemaSymbols::fgELT_SIMPLECONTENT)) {                // SIMPLE CONTENT element                traverseSimpleContentDecl(name, fullName, child, typeInfo, &janAnnot);                if (XUtil::getNextSiblingElement(child) != 0) {                    reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildFollowingSimpleContent);                }            }            else if (XMLString::equals(childName, SchemaSymbols::fgELT_COMPLEXCONTENT)) {                // COMPLEX CONTENT element                traverseComplexContentDecl(name, child, typeInfo, isMixed, &janAnnot);                if (XUtil::getNextSiblingElement(child) != 0) {                    reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildFollowingConplexContent);                }            }            else if (fCurrentGroupInfo) {                typeInfo->setPreprocessed(true);            }            else {                // We must have ....                // GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes                // Note that it's possible that only attributes are specified.                processComplexContent(elem, name, child, typeInfo, 0, isMixed);            }        }    }    catch(const TraverseSchema::ExceptionCodes aCode) {        if (aCode == TraverseSchema::InvalidComplexTypeInfo)            defaultComplexTypeInfo(typeInfo);        else if (aCode == TraverseSchema::RecursingElement)            typeInfo->setPreprocessed();    }    // ------------------------------------------------------------------    // Finish the setup of the typeInfo    // ------------------------------------------------------------------    if (!preProcessFlag) {        const XMLCh* abstractAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT);        int blockSet = parseBlockSet(elem, C_Block);        int finalSet = parseFinalSet(elem, EC_Final);        typeInfo->setBlockSet(blockSet);        typeInfo->setFinalSet(finalSet);        if ((abstractAttVal && *abstractAttVal)            && (XMLString::equals(abstractAttVal, SchemaSymbols::fgATTVAL_TRUE)                || XMLString::equals(abstractAttVal, fgValueOne))) {            typeInfo->setAbstract(true);        }        else {            typeInfo->setAbstract(false);        }    }    // Store Annotation    if (!janAnnot.isDataNull())        fSchemaGrammar->putAnnotation(typeInfo, janAnnot.release());    // ------------------------------------------------------------------    // Before exiting, restore the scope, mainly for nested anonymous types    // ------------------------------------------------------------------    popCurrentTypeNameStack();    fCircularCheckIndex = previousCircularCheckIndex;    fCurrentScope = previousScope;    fCurrentComplexType = saveTypeInfo;

⌨️ 快捷键说明

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