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();
}
}