void TraverseSchema::processChildren()

in src/xercesc/validators/schema/TraverseSchema.cpp [4733:4926]


void TraverseSchema::processChildren(const DOMElement* const root) {

    NamespaceScopeManager nsMgr(root, fSchemaInfo, this);

    bool sawAnnotation = false;
    // process <redefine>, <include> and <import> info items.
    DOMElement* child = XUtil::getFirstChildElement(root);

    for (; child != 0; child = XUtil::getNextSiblingElement(child)) {

        const XMLCh* name = child->getLocalName();

        if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) {
            XSAnnotation* annot = traverseAnnotationDecl(
                    child, fSchemaInfo->getNonXSAttList(), true);
            if (annot) {
                fSchemaGrammar->addAnnotation(annot);
                sawAnnotation = true;
            }
        }
        else if (XMLString::equals(name, SchemaSymbols::fgELT_INCLUDE)) {
            traverseInclude(child);
        }
        else if (XMLString::equals(name, SchemaSymbols::fgELT_IMPORT)) {
            traverseImport(child);
        }
        else if (XMLString::equals(name, SchemaSymbols::fgELT_REDEFINE)) {
            traverseRedefine(child);
        }
        else
            break;
    }

    // child refers to the first info item which is not <annotation> or
    // one of the schema inclusion/importation declarations.
    for (; child != 0; child = XUtil::getNextSiblingElement(child)) {

        const XMLCh* name = child->getLocalName();
        const XMLCh* typeName = getElementAttValue(child, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName);
        int fullNameId = 0;

        if (typeName) {

            fBuffer.set(fTargetNSURIString);
            fBuffer.append(chComma);
            fBuffer.append(typeName);
            fullNameId = fStringPool->addOrFind(fBuffer.getRawBuffer());
        }

        if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) {
            XSAnnotation* annot = traverseAnnotationDecl(
                    child, fSchemaInfo->getNonXSAttList(), true);
            if (annot) {
                fSchemaGrammar->addAnnotation(annot);
                sawAnnotation = true;
            }
        }
        else if (XMLString::equals(name, SchemaSymbols::fgELT_SIMPLETYPE)) {

            if (typeName && *typeName) {
                if (fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->containsElement(fullNameId)
                    || fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->containsElement(fullNameId)) {

                    reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
                                      SchemaSymbols::fgELT_SIMPLETYPE, typeName, SchemaSymbols::fgELT_COMPLEXTYPE);
                    continue;
                }
                else {
                    fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->addElement(fullNameId);
                }
            }

            traverseSimpleTypeDecl(child);
        }
        else if (XMLString::equals(name, SchemaSymbols::fgELT_COMPLEXTYPE)) {

            if (typeName && *typeName) {
                if (fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->containsElement(fullNameId)
                    || fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->containsElement(fullNameId)) {

                    reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
                                      SchemaSymbols::fgELT_COMPLEXTYPE, typeName, SchemaSymbols::fgELT_SIMPLETYPE);
                    continue;
                }
                else {
                    fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->addElement(fullNameId);
                }
            }

            traverseComplexTypeDecl(child);
        }
        else if (XMLString::equals(name, SchemaSymbols::fgELT_ELEMENT)) {

            if (typeName && *typeName) {
                if (fGlobalDeclarations[ENUM_ELT_ELEMENT]->containsElement(fullNameId)) {

                    reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
                                      SchemaSymbols::fgELT_ELEMENT, typeName);
                    continue;
                }
                else {
                    fGlobalDeclarations[ENUM_ELT_ELEMENT]->addElement(fullNameId);
                }
            }

            traverseElementDecl(child, true);
        }
        else if (XMLString::equals(name, SchemaSymbols::fgELT_ATTRIBUTEGROUP)) {

            if (typeName && *typeName) {
                if (fGlobalDeclarations[ENUM_ELT_ATTRIBUTEGROUP]->containsElement(fullNameId)) {

                    reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
                                      SchemaSymbols::fgELT_ATTRIBUTEGROUP, typeName);
                    continue;
                }
                else {
                    fGlobalDeclarations[ENUM_ELT_ATTRIBUTEGROUP]->addElement(fullNameId);
                }
            }

            if (!typeName || !fAttGroupRegistry->containsKey(typeName)) {
                traverseAttributeGroupDecl(child, 0, true);
            }
        }
        else if (XMLString::equals(name, SchemaSymbols::fgELT_ATTRIBUTE)) {

            if (typeName && *typeName) {
                if (fGlobalDeclarations[ENUM_ELT_ATTRIBUTE]->containsElement(fullNameId)) {

                    reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, typeName);
                    continue;
                }
                else {
                    fGlobalDeclarations[ENUM_ELT_ATTRIBUTE]->addElement(fullNameId);
                }
            }

            if (!typeName || !fAttributeDeclRegistry->containsKey(typeName)) {
                traverseAttributeDecl( child, 0, true);
            }
        }
        else if (XMLString::equals(name, SchemaSymbols::fgELT_GROUP)) {

            if (typeName && *typeName) {
                if (fGlobalDeclarations[ENUM_ELT_GROUP]->containsElement(fullNameId)) {

                    reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
                                      SchemaSymbols::fgELT_GROUP, typeName);
                    continue;
                }
                else {
                    fGlobalDeclarations[ENUM_ELT_GROUP]->addElement(fullNameId);
                }
            }

            if (!typeName || !fGroupRegistry->containsKey(fBuffer.getRawBuffer())) {
                traverseGroupDecl(child);
            }
        }
        else if (XMLString::equals(name, SchemaSymbols::fgELT_NOTATION)) {
            traverseNotationDecl(child);
        }
        else {
            reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::SchemaElementContentError);
        }
    } // for each child node


    if (fScanner->getGenerateSyntheticAnnotations() && fSchemaInfo->getNonXSAttList()->size() && !sawAnnotation)
    {
        // synthesize a global annotation here.
        fSchemaGrammar->addAnnotation(
                generateSyntheticAnnotation(root, fSchemaInfo->getNonXSAttList())
            );
    }

    // Handle recursing elements - if any
    ValueVectorOf<const DOMElement*>* recursingAnonTypes = fSchemaInfo->getRecursingAnonTypes();

    if (recursingAnonTypes) {

        ValueVectorOf<const XMLCh*>* recursingTypeNames = fSchemaInfo->getRecursingTypeNames();
        XMLSize_t recurseSize = recursingAnonTypes->size();

        for (XMLSize_t i=0; i < recurseSize; i++) {
            traverseComplexTypeDecl(recursingAnonTypes->elementAt(i), false,
                                    recursingTypeNames->elementAt(i));
        }

        recursingAnonTypes->removeAllElements();
        recursingTypeNames->removeAllElements();
    }
}