TraverseSchema.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:302k
源码类别:

词法分析

开发平台:

Visual C++

  1.                 if (!typeInfo) {
  2.                     validator = getElementTypeValidator(elem, typeStr, noErrorFound, anotherSchemaURI);
  3.                 }
  4.             }
  5.         }
  6.     }
  7.     // Set element declararion type information
  8.     if (!isDuplicate) {
  9.         elemDecl->setDatatypeValidator(validator);
  10.         elemDecl->setComplexTypeInfo(typeInfo);
  11.     }
  12.     if (topLevel) {
  13.         // Handle the substitutionGroup
  14.         const XMLCh* subsGroupName = getElementAttValue(elem, SchemaSymbols::fgATT_SUBSTITUTIONGROUP);
  15.         if (subsGroupName && *subsGroupName) {
  16.             SchemaElementDecl* subsElemDecl = getSubstituteGroupElemDecl
  17.             (
  18.                 elem
  19.                 , subsGroupName
  20.                 , noErrorFound
  21.             );
  22.             if (subsElemDecl) {
  23.                 if (isSubstitutionGroupCircular(elemDecl, subsElemDecl)) {
  24.                     reportSchemaError
  25.                     (
  26.                         elem
  27.                         , XMLUni::fgXMLErrDomain
  28.                         , XMLErrs::CircularSubsGroup
  29.                         , name
  30.                     );
  31.                 }
  32.                 else {
  33.                     // Check for substitution validity constraint
  34.                     // Substitution allowed (block and blockDefault) && same type
  35.                     if (isSubstitutionGroupValid(elem, subsElemDecl,typeInfo,validator,name)) {
  36.                         if (typeInfo == 0 && validator == 0 && noErrorFound) {
  37.                             typeInfo = subsElemDecl->getComplexTypeInfo();
  38.                             validator = subsElemDecl->getDatatypeValidator();
  39.                         }
  40.                         if (!isDuplicate) {
  41.                             XMLCh* elemBaseName = elemDecl->getBaseName();
  42.                             XMLCh* subsElemBaseName = subsElemDecl->getBaseName();
  43.                             int    elemURI = elemDecl->getURI();
  44.                             int    subsElemURI = subsElemDecl->getURI();
  45.                             elemDecl->setSubstitutionGroupElem(subsElemDecl);
  46.                             ValueVectorOf<SchemaElementDecl*>* subsElements =
  47.                                 fValidSubstitutionGroups->get(subsElemBaseName, subsElemURI);
  48.                             if (!subsElements && fTargetNSURI != subsElemURI) {
  49.                                 SchemaGrammar* aGrammar = (SchemaGrammar*)
  50.                                    fGrammarResolver->getGrammar(fURIStringPool->getValueForId(subsElemURI));
  51.                                 if (aGrammar) {
  52.                                     subsElements = aGrammar->getValidSubstitutionGroups()->get(subsElemBaseName, subsElemURI);
  53.                                     if (subsElements) {
  54.                                         subsElements = new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(*subsElements);
  55.                                         fValidSubstitutionGroups->put(subsElemBaseName, subsElemURI, subsElements);
  56.                                     }
  57.                                     else if (fSchemaInfo->circularImportExist(subsElemURI)) {
  58.                                         aGrammar->getValidSubstitutionGroups()->put(
  59.                                         subsElemBaseName, subsElemURI, new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(8, fMemoryManager));
  60.                                     }
  61.                                 }
  62.                             }
  63.                             if (!subsElements) {
  64.                                 subsElements = new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(8, fMemoryManager);
  65.                                 fValidSubstitutionGroups->put(subsElemBaseName, subsElemURI, subsElements);
  66.                             }
  67.                             subsElements->addElement(elemDecl);
  68.                             // update related subs. info in case of circular import
  69.                             BaseRefVectorEnumerator<SchemaInfo> importingEnum = fSchemaInfo->getImportingListEnumerator();
  70.                             while (importingEnum.hasMoreElements()) {
  71.                                 const SchemaInfo& curRef = importingEnum.nextElement();
  72.                                 SchemaGrammar* aGrammar = (SchemaGrammar*)
  73.                                     fGrammarResolver->getGrammar(curRef.getTargetNSURIString());
  74.                                 ValueVectorOf<SchemaElementDecl*>* subsElemList =
  75.                                     aGrammar->getValidSubstitutionGroups()->get(subsElemBaseName, subsElemURI);
  76.                                 if (subsElemList && !subsElemList->containsElement(elemDecl))
  77.                                     subsElemList->addElement(elemDecl);
  78.                             }
  79.                             buildValidSubstitutionListB(elem, elemDecl, subsElemDecl);
  80.                             buildValidSubstitutionListF(elem, elemDecl, subsElemDecl);
  81.                         }
  82.                     }
  83.                     else {
  84.                         noErrorFound = false;
  85.                     }
  86.                 }
  87.             }
  88.         }
  89.     }
  90.     bool isAnyType = false;
  91.     if (typeInfo == 0 && validator == 0) {
  92.         if (noErrorFound) { // ur type
  93.             contentSpecType = SchemaElementDecl::Any;
  94.             isAnyType = true;
  95.         }
  96.         else {
  97.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::UntypedElement, name);
  98.         }
  99.     }
  100.     // if element belongs to a compelx type
  101.     if (typeInfo != 0) {
  102.         contentSpecNode = typeInfo->getContentSpec();
  103.         contentSpecType = (SchemaElementDecl::ModelTypes) typeInfo->getContentType();
  104.         scopeDefined = typeInfo->getScopeDefined();
  105.         validator = typeInfo->getDatatypeValidator();
  106.     }
  107.     // if element belongs to a simple type
  108.     if (validator != 0) {
  109.         contentSpecType = SchemaElementDecl::Simple;
  110.     }
  111.     // Now we can handle validation etc. of default and fixed attributes,
  112.     // since we finally have all the type information.
  113.     if(fixed && *fixed) {
  114.         deflt = fixed;
  115.     }
  116.     if(deflt && *deflt) {
  117.         try {
  118.             if(validator == 0) { // in this case validate according to xs:string
  119.                 fDatatypeRegistry->getDatatypeValidator(SchemaSymbols::fgDT_STRING)->validate(deflt);
  120.             } else {
  121.                 validator->validate(deflt);
  122.             }
  123.         }
  124.         catch (const XMLException& excep) {
  125.             reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  126.         }
  127.         catch(...) {
  128.             reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, deflt);
  129.         }
  130.         if(typeInfo != 0 &&
  131.            contentSpecType != SchemaElementDecl::Simple &&
  132.            contentSpecType != SchemaElementDecl::Mixed_Simple &&
  133.            contentSpecType != SchemaElementDecl::Mixed_Complex) {
  134.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NotSimpleOrMixedElement, name);
  135.         }
  136.         if(typeInfo != 0 &&
  137.            ((contentSpecType == SchemaElementDecl::Mixed_Complex
  138.              || contentSpecType == SchemaElementDecl::Mixed_Simple)
  139.             && !emptiableParticle(contentSpecNode))) {
  140.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::EmptiableMixedContent, name);
  141.         }
  142.         if (validator && (validator->getType() == DatatypeValidator::ID)) {
  143.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ElemIDValueConstraint, name, deflt);
  144.         }
  145.     }
  146.     // set element information, but first check for duplicate elements with
  147.     // different types.
  148.     if (isDuplicate) {
  149.         DatatypeValidator* eltDV = elemDecl->getDatatypeValidator();
  150.         ComplexTypeInfo*   eltTypeInfo = elemDecl->getComplexTypeInfo();
  151.         if ( (eltTypeInfo != typeInfo) || (eltDV != validator))  {
  152.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, name);
  153.         }
  154.     }
  155.     else {
  156.         elemDecl->setDatatypeValidator(validator);
  157.         elemDecl->setComplexTypeInfo(typeInfo);
  158.         elemDecl->setDefaultValue(deflt);
  159.         elemDecl->setModelType(contentSpecType);
  160.         elemDecl->setContentSpec(contentSpecNode);
  161.         if (isAnyType) {
  162.             elemDecl->setAttWildCard(new (fMemoryManager) SchemaAttDef(XMLUni::fgZeroLenString,
  163.                                                       XMLUni::fgZeroLenString,
  164.                                                       fEmptyNamespaceURI, XMLAttDef::Any_Any,
  165.                                                       XMLAttDef::ProcessContents_Lax,
  166.                                                       fMemoryManager));
  167.         }
  168.         // key/keyref/unique processing
  169.         DOMElement* ic = XUtil::getFirstChildElementNS(elem, fgIdentityConstraints,
  170.                                                          SchemaSymbols::fgURI_SCHEMAFORSCHEMA, 3);
  171.         ValueVectorOf<DOMElement*>* icNodes = 0;
  172.         while (ic != 0) {
  173.             if (XMLString::equals(ic->getLocalName(), SchemaSymbols::fgELT_KEY)) {
  174.                 traverseKey(ic, elemDecl);
  175.             }
  176.             else if (XMLString::equals(ic->getLocalName(), SchemaSymbols::fgELT_UNIQUE)) {
  177.                 traverseUnique(ic, elemDecl);
  178.             }
  179.             else {
  180.                 if (!icNodes) {
  181.                     icNodes = new (fMemoryManager) ValueVectorOf<DOMElement*>(8, fMemoryManager);
  182.                 }
  183.                 icNodes->addElement(ic);
  184.             }
  185.             ic = XUtil::getNextSiblingElementNS(ic, fgIdentityConstraints,
  186.                                                 SchemaSymbols::fgURI_SCHEMAFORSCHEMA, 3);
  187.         }
  188.         if (icNodes) {
  189.             if (!fIC_ElementsNS) {
  190.                 fIC_ElementsNS = new (fMemoryManager) RefHashTableOf<ElemVector>(13, fMemoryManager);
  191.                 fIC_NamespaceDepthNS = new (fMemoryManager) RefHashTableOf<ValueVectorOf<unsigned int> >(13, fMemoryManager);
  192.                 fIC_NodeListNS = new (fMemoryManager) RefHashTableOf<ValueVectorOf<DOMElement*> >(29, true, new (fMemoryManager) HashPtr(), fMemoryManager);
  193.             }
  194.             if (fIC_ElementsNS->containsKey(fTargetNSURIString)) {
  195.                 fIC_Elements = fIC_ElementsNS->get(fTargetNSURIString);
  196.                 fIC_NamespaceDepth = fIC_NamespaceDepthNS->get(fTargetNSURIString);
  197.             }
  198.             if (!fIC_Elements) {
  199.                 fIC_Elements = new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(8, fMemoryManager);
  200.                 fIC_NamespaceDepth = new (fMemoryManager) ValueVectorOf<unsigned int>(8, fMemoryManager);
  201.                 fIC_ElementsNS->put((void*) fTargetNSURIString, fIC_Elements);
  202.                 fIC_NamespaceDepthNS->put((void*) fTargetNSURIString, fIC_NamespaceDepth);
  203.             }
  204.             fIC_NodeListNS->put(elemDecl, icNodes);
  205.             fIC_Elements->addElement(elemDecl);
  206.             fIC_NamespaceDepth->addElement(fSchemaInfo->getNamespaceScopeLevel());
  207.         }
  208.     }
  209.     return new (fMemoryManager) QName(*elemDecl->getElementName());
  210. }
  211. const XMLCh* TraverseSchema::traverseNotationDecl(const DOMElement* const elem) {
  212.     // ------------------------------------------------------------------
  213.     // Check attributes
  214.     // ------------------------------------------------------------------
  215.     fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_Notation, this, true);
  216.     // ------------------------------------------------------------------
  217.     // Process notation attributes/elements
  218.     // ------------------------------------------------------------------
  219.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  220.     bool         nameEmpty = (!name || !*name) ? true : false;
  221.     if (nameEmpty) {
  222.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,
  223.                           SchemaSymbols::fgELT_NOTATION);
  224.         return 0;
  225.     }
  226.     if (fNotationRegistry->containsKey(name, fTargetNSURI)) {
  227.         return name;
  228.     }
  229.     const XMLCh* publicId = getElementAttValue(elem, SchemaSymbols::fgATT_PUBLIC);
  230.     const XMLCh* systemId = getElementAttValue(elem, SchemaSymbols::fgATT_SYSTEM);
  231.     fNotationRegistry->put((void*) fStringPool->getValueForId(fStringPool->addOrFind(name)),
  232.                            fTargetNSURI, 0);
  233.     //we don't really care if something inside <notation> is wrong..
  234.     checkContent(elem, XUtil::getFirstChildElement(elem), true);
  235.     return name;
  236. }
  237. const XMLCh* TraverseSchema::traverseNotationDecl(const DOMElement* const elem,
  238.                                                   const XMLCh* const name,
  239.                                                   const XMLCh* const uriStr) {
  240.     unsigned int uriId = fURIStringPool->addOrFind(uriStr);
  241.     SchemaInfo*  saveInfo = fSchemaInfo;
  242.     if (fTargetNSURI != (int) uriId) {
  243.         // Make sure that we have an explicit import statement.
  244.         // Clause 4 of Schema Representation Constraint:
  245.         // http://www.w3.org/TR/xmlschema-1/#src-resolve
  246.         unsigned int uriId = fURIStringPool->addOrFind(uriStr);
  247.         if (!fSchemaInfo->isImportingNS(uriId)) {
  248.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr);
  249.             return 0;
  250.         }
  251.         Grammar* grammar = fGrammarResolver->getGrammar(uriStr);
  252.         if (grammar == 0 || grammar->getGrammarType() != Grammar::SchemaGrammarType) {
  253.             reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
  254.             return 0;
  255.         }
  256.         SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
  257.         if (!impInfo || impInfo->getProcessed()) {
  258.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, uriStr, name);
  259.             return 0;
  260.         }
  261.         fSchemaInfo = impInfo;
  262.         fTargetNSURI = fSchemaInfo->getTargetNSURI();
  263.     }
  264.     DOMElement* notationElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Notation,
  265.         SchemaSymbols::fgELT_NOTATION, name, &fSchemaInfo);
  266.     if (notationElem == 0) {
  267.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::Notation_DeclNotFound, uriStr, name);
  268.         return 0;
  269.     }
  270.     const XMLCh* notationName = traverseNotationDecl(notationElem);
  271.     fSchemaInfo = saveInfo;
  272.     fTargetNSURI = fSchemaInfo->getTargetNSURI();
  273.     return notationName;
  274. }
  275. DatatypeValidator*
  276. TraverseSchema::traverseByList(const DOMElement* const rootElem,
  277.                                const DOMElement* const contentElem,
  278.                                const XMLCh* const typeName,
  279.                                const XMLCh* const qualifiedName,
  280.                                const int finalSet) {
  281.     DatatypeValidator* baseValidator = 0;
  282.     const XMLCh*       baseTypeName = getElementAttValue(contentElem, SchemaSymbols::fgATT_ITEMTYPE);
  283.     fAttributeCheck.checkAttributes(contentElem, GeneralAttributeCheck::E_List, this);
  284.     if (XUtil::getNextSiblingElement(contentElem) != 0) {
  285.         reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError);
  286.     }
  287.     DOMElement*      content = 0;
  288.     if (!baseTypeName || !*baseTypeName) { // must 'see' <simpleType>
  289.         content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false);
  290.         if (!content) {
  291.             reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInList, typeName);
  292.             popCurrentTypeNameStack();
  293.             return 0;
  294.         }
  295.         if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) {
  296.             baseValidator = checkForSimpleTypeValidator(content, SchemaSymbols::XSD_LIST);
  297.         }
  298.         else {
  299.             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
  300.             popCurrentTypeNameStack();
  301.             return 0;
  302.         }
  303.         content = XUtil::getNextSiblingElement(content);
  304.     }
  305.     else { // base was provided - get proper validator
  306.         baseValidator = findDTValidator(contentElem, typeName, baseTypeName, SchemaSymbols::XSD_LIST);
  307.         content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true);
  308.     }
  309.     DatatypeValidator* newDV = 0;
  310.     if (baseValidator) {
  311.         if (!baseValidator->isAtomic()) {
  312.             reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::AtomicItemType, baseTypeName);
  313.         }
  314.         else {
  315.             // 'content' should be empty
  316.             // If an annotation was encountered we have already traversed it in
  317.             // checkContent in the case of a base provided (only allowed child is
  318.             // an annotation).
  319.             if (content != 0) { // report an error and continue
  320.                 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeDerivationByListError, typeName);
  321.             }
  322.             // create & register validator for "generated" type
  323.             try {
  324.                 newDV = fDatatypeRegistry->createDatatypeValidator(
  325.                     qualifiedName, baseValidator, 0, 0, true, finalSet);
  326.             }
  327.             catch (const XMLException& excep) {
  328.                 reportSchemaError(contentElem, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  329.             }
  330.             catch(...) {
  331.                 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain,
  332.                                   XMLErrs::DatatypeValidatorCreationError, typeName);
  333.             }
  334.         }
  335.     }
  336.     popCurrentTypeNameStack();
  337.     return newDV;
  338. }
  339. DatatypeValidator*
  340. TraverseSchema::traverseByRestriction(const DOMElement* const rootElem,
  341.                                       const DOMElement* const contentElem,
  342.                                       const XMLCh* const typeName,
  343.                                       const XMLCh* const qualifiedName,
  344.                                       const int finalSet) {
  345.     DatatypeValidator* baseValidator = 0;
  346.     DatatypeValidator* newDV = 0;
  347.     const XMLCh*       baseTypeName = getElementAttValue(contentElem, SchemaSymbols::fgATT_BASE);
  348.     fAttributeCheck.checkAttributes(contentElem, GeneralAttributeCheck::E_Restriction, this);
  349.     if (XUtil::getNextSiblingElement(contentElem) != 0) {
  350.         reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError);
  351.     }
  352.     DOMElement* content = 0;
  353.     if (!baseTypeName || !*baseTypeName) { // must 'see' <simpleType>
  354.         content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false);
  355.         if (content == 0) {
  356.             reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInRestriction);
  357.             popCurrentTypeNameStack();
  358.             return 0;
  359.         }
  360.         if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) {
  361.             baseValidator = checkForSimpleTypeValidator(content);
  362.         }
  363.         else {
  364.             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
  365.             popCurrentTypeNameStack();
  366.             return 0;
  367.         }
  368.         // Check for facets
  369.         content = XUtil::getNextSiblingElement(content);
  370.     }
  371.     else { // base was provided - get proper validator
  372.         baseValidator = findDTValidator(contentElem, typeName, baseTypeName, SchemaSymbols::XSD_RESTRICTION);
  373.         content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true);
  374.     }
  375.     if (baseValidator) {
  376.         // Get facets if any existing
  377.         RefHashTableOf<KVStringPair>* facets = 0;
  378.         RefArrayVectorOf<XMLCh>*      enums = 0;
  379.         XMLBuffer                     pattern(128, fMemoryManager);
  380.         XMLCh                         fixedFlagStr[16];
  381.         unsigned int                  fixedFlag = 0;
  382.         unsigned short                scope = 0;
  383.         bool                          isFirstPattern = true;
  384.         while (content != 0) {
  385.             if (content->getNodeType() == DOMNode::ELEMENT_NODE) {
  386.                 const XMLCh* facetName = content->getLocalName();
  387.                 try {
  388.                     scope = fAttributeCheck.getFacetId(facetName);
  389.                 }
  390.                 catch (...) {
  391.                     reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::InvalidFacetName, facetName);
  392.                     content = XUtil::getNextSiblingElement(content);
  393.                     continue;
  394.                 }
  395.                 const XMLCh* attValue = content->getAttribute(SchemaSymbols::fgATT_VALUE);
  396.                 fAttributeCheck.checkAttributes(content, scope, this);
  397.                 if (facets == 0) {
  398.                     facets = new (fMemoryManager) RefHashTableOf<KVStringPair>(29, true, fMemoryManager);
  399.                 }
  400.                 if (XMLString::equals(facetName, SchemaSymbols::fgELT_ENUMERATION)) {
  401.                     // REVISIT
  402.                     // if validator is a notation datatype validator, we need
  403.                     // to get the qualified name first before adding it to the
  404.                     // enum buffer
  405.                     if (!enums) {
  406.                         enums = new (fMemoryManager) RefArrayVectorOf<XMLCh>(8, true, fMemoryManager);
  407.                     }
  408.                     if (baseValidator->getType() == DatatypeValidator::NOTATION) {
  409.                         const XMLCh* localPart = getLocalPart(attValue);
  410.                         const XMLCh* prefix = getPrefix(attValue);
  411.                         const XMLCh* uriStr = (prefix && *prefix) ? resolvePrefixToURI(content, prefix) : fTargetNSURIString;
  412.                         unsigned int uriId = fURIStringPool->addOrFind(uriStr);
  413.                         if (!fNotationRegistry->containsKey(localPart, uriId)) {
  414.                             traverseNotationDecl(content, localPart, uriStr);
  415.                         }
  416.                         fBuffer.set(uriStr);
  417.                         fBuffer.append(chColon);
  418.                         fBuffer.append(localPart);
  419.                         enums->addElement(XMLString::replicate(fBuffer.getRawBuffer(), fMemoryManager));
  420.                     }
  421.                     else {
  422.                         enums->addElement(XMLString::replicate(attValue, fMemoryManager));
  423.                     }
  424.                 }
  425.                 else if (XMLString::equals(facetName, SchemaSymbols::fgELT_PATTERN)) {
  426.                     if (isFirstPattern) { // fBuffer.isEmpty() - overhead call
  427.                         isFirstPattern = false;
  428.                         pattern.set(attValue);
  429.                     }
  430.                     else { //datatypes: 5.2.4 pattern
  431.                         pattern.append(chPipe);
  432.                         pattern.append(attValue);
  433.                     }
  434.                 }
  435.                 else {
  436.                     if (facets->containsKey(facetName)) {
  437.                         reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateFacet, facetName);
  438.                     }
  439.                     else {
  440.                         if (XMLString::equals(facetName, SchemaSymbols::fgELT_WHITESPACE)
  441.                             && baseValidator->getType() != DatatypeValidator::String
  442.                             && !XMLString::equals(attValue, SchemaSymbols::fgWS_COLLAPSE)) {
  443.                             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::WS_CollapseExpected, attValue);
  444.                         }
  445.                         else {
  446.                             const XMLCh* facetStr = fStringPool->getValueForId(fStringPool->addOrFind(facetName));
  447.                             facets->put((void*) facetStr, new (fMemoryManager) KVStringPair(facetStr, attValue, fMemoryManager));
  448.                             checkFixedFacet(content, facetStr, baseValidator, fixedFlag);
  449.                         }
  450.                     }
  451.                 }
  452.                 // REVISIT
  453.                 // check for annotation content - we are not checking whether the
  454.                 // return is empty or not. If not empty we should report an error
  455.                 checkContent(rootElem, XUtil::getFirstChildElement(content), true);
  456.             }
  457.             content = XUtil::getNextSiblingElement(content);
  458.         } // end while
  459.         if (!pattern.isEmpty()) {
  460.             facets->put((void*) SchemaSymbols::fgELT_PATTERN,
  461.                         new (fMemoryManager) KVStringPair(SchemaSymbols::fgELT_PATTERN, pattern.getRawBuffer(), fMemoryManager));
  462.         }
  463.         if (fixedFlag) {
  464.             XMLString::binToText(fixedFlag, fixedFlagStr, 15, 10);
  465.             facets->put((void*) SchemaSymbols::fgATT_FIXED,
  466.                         new (fMemoryManager) KVStringPair(SchemaSymbols::fgATT_FIXED, fixedFlagStr, fMemoryManager));
  467.         }
  468.         try {
  469.             newDV = fDatatypeRegistry->createDatatypeValidator(qualifiedName, baseValidator, facets, enums, false, finalSet);
  470.         }
  471.         catch (const XMLException& excep) {
  472.             reportSchemaError(contentElem, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  473.         }
  474.         catch(...) {
  475.             reportSchemaError(contentElem, XMLUni::fgXMLErrDomain,
  476.                               XMLErrs::DatatypeValidatorCreationError, typeName);
  477.         }
  478.     }
  479.     popCurrentTypeNameStack();
  480.     return newDV;
  481. }
  482. DatatypeValidator*
  483. TraverseSchema::traverseByUnion(const DOMElement* const rootElem,
  484.                                 const DOMElement* const contentElem,
  485.                                 const XMLCh* const typeName,
  486.                                 const XMLCh* const qualifiedName,
  487.                                 const int finalSet,
  488.                                 int baseRefContext) {
  489.     fAttributeCheck.checkAttributes(contentElem, GeneralAttributeCheck::E_Union, this);
  490.     if (XUtil::getNextSiblingElement(contentElem) != 0) {
  491.         reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError);
  492.     }
  493.     int                             size = 1;
  494.     const XMLCh*                    baseTypeName = getElementAttValue(contentElem, SchemaSymbols::fgATT_MEMBERTYPES);
  495.     DatatypeValidator*              baseValidator = 0;
  496.     RefVectorOf<DatatypeValidator>* validators = new (fMemoryManager) RefVectorOf<DatatypeValidator>(4, false, fMemoryManager);
  497.     Janitor<DVRefVector>            janValidators(validators);
  498.     DOMElement*                     content = 0;
  499.     if (baseTypeName && *baseTypeName) { //base was provided - get proper validator.
  500.         XMLStringTokenizer unionMembers(baseTypeName, fMemoryManager);
  501.         int             tokCount = unionMembers.countTokens();
  502.         for (int i = 0; i < tokCount; i++) {
  503.             const XMLCh* memberTypeName = unionMembers.nextToken();
  504.             baseValidator = findDTValidator(contentElem, typeName, memberTypeName, SchemaSymbols::XSD_UNION);
  505.             if (baseValidator == 0) {
  506.                 popCurrentTypeNameStack();
  507.                 return 0;
  508.             }
  509.             validators->addElement(baseValidator);
  510.         }
  511.         content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true);
  512.     }
  513.     else { // must 'see' <simpleType>
  514.         content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false);
  515.         if (content == 0) {
  516.             reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInUnion, typeName);
  517.             popCurrentTypeNameStack();
  518.             return 0;
  519.         }
  520.         if (!XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) {
  521.             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
  522.             popCurrentTypeNameStack();
  523.             return 0;
  524.         }
  525.     }
  526.     // process union content of simpleType children if any
  527.     while (content != 0) {
  528.         if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) {
  529.             baseValidator = checkForSimpleTypeValidator(content, baseRefContext | SchemaSymbols::XSD_UNION);
  530.             if (baseValidator == 0) {
  531.                 popCurrentTypeNameStack();
  532.                 return 0;
  533.             }
  534.             validators->addElement(baseValidator);
  535.         }
  536.         else {
  537.             // REVISIT - should we break. For now, we will continue and move to
  538.             // the next sibling
  539.             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
  540.         }
  541.         content   = XUtil::getNextSiblingElement(content);
  542.     } // end while
  543.     DatatypeValidator* newDV = 0;
  544.     janValidators.orphan();
  545.     try {
  546.         newDV = fDatatypeRegistry->createDatatypeValidator(qualifiedName, validators, finalSet);
  547.     }
  548.     catch (const XMLException& excep) {
  549.         reportSchemaError(contentElem, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  550.     }
  551.     catch(...) {
  552.         reportSchemaError(contentElem, XMLUni::fgXMLErrDomain,
  553.                           XMLErrs::DatatypeValidatorCreationError, typeName);
  554.     }
  555.     popCurrentTypeNameStack();
  556.     return newDV;
  557. }
  558. /**
  559.   * Traverse SimpleContent Declaration
  560.   *
  561.   *   <simpleContent
  562.   *     id = ID
  563.   *     {any attributes with non-schema namespace...}>
  564.   *
  565.   *     Content: (annotation? , (restriction | extension))
  566.   *   </simpleContent>
  567.   *
  568.   *   <restriction
  569.   *     base = QNAME
  570.   *     id = ID
  571.   *     {any attributes with non-schema namespace...}>
  572.   *
  573.   *     Content: (annotation?, (simpleType?, (minExclusive | minInclusive
  574.   *               | maxExclusive | maxInclusive | totalDigits | fractionDigits
  575.   *               | length | minLength | maxLength | enumeration | pattern
  576.   *               | whiteSpace)*)?, ((attribute | attributeGroup)* , anyAttribute?))
  577.   *   </restriction>
  578.   *
  579.   *   <extension
  580.   *     base = QNAME
  581.   *     id = ID
  582.   *     {any attributes with non-schema namespace...}>
  583.   *     Content: (annotation? , ((attribute | attributeGroup)* , anyAttribute?))
  584.   *   </extension>
  585.   *
  586.   */
  587. void TraverseSchema::traverseSimpleContentDecl(const XMLCh* const typeName,
  588.                                                const XMLCh* const qualifiedName,
  589.                                                const DOMElement* const contentDecl,
  590.                                                ComplexTypeInfo* const typeInfo)
  591. {
  592.     // -----------------------------------------------------------------------
  593.     // Check Attributes
  594.     // -----------------------------------------------------------------------
  595.     fAttributeCheck.checkAttributes(contentDecl, GeneralAttributeCheck::E_SimpleContent, this);
  596.     // -----------------------------------------------------------------------
  597.     // Set the content type to be simple, and initialize content spec handle
  598.     // -----------------------------------------------------------------------
  599.     typeInfo->setContentType(SchemaElementDecl::Simple);
  600.     DOMElement* simpleContent = checkContent(contentDecl, XUtil::getFirstChildElement(contentDecl), false);
  601.     // If there are no children, return
  602.     if (simpleContent == 0) {
  603.         reportSchemaError(contentDecl, XMLUni::fgXMLErrDomain, XMLErrs::EmptySimpleTypeContent);
  604.         throw TraverseSchema::InvalidComplexTypeInfo;
  605.     }
  606.     // -----------------------------------------------------------------------
  607.     // The content should be either "restriction" or "extension"
  608.     // -----------------------------------------------------------------------
  609.     const XMLCh* const contentName = simpleContent->getLocalName();
  610.     if (XMLString::equals(contentName, SchemaSymbols::fgATTVAL_RESTRICTION)) {
  611.         fAttributeCheck.checkAttributes(simpleContent, GeneralAttributeCheck::E_Restriction, this);
  612.         typeInfo->setDerivedBy(SchemaSymbols::XSD_RESTRICTION);
  613.     }
  614.     else if (XMLString::equals(contentName, SchemaSymbols::fgATTVAL_EXTENSION)) {
  615.         fAttributeCheck.checkAttributes(simpleContent, GeneralAttributeCheck::E_Extension, this);
  616.         typeInfo->setDerivedBy(SchemaSymbols::XSD_EXTENSION);
  617.     }
  618.     else {
  619.         reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContent);
  620.         throw TraverseSchema::InvalidComplexTypeInfo;
  621.     }
  622.     // -----------------------------------------------------------------------
  623.     // Handle the base type name
  624.     // -----------------------------------------------------------------------
  625.     const XMLCh* baseName = getElementAttValue(simpleContent, SchemaSymbols::fgATT_BASE);
  626.     if (!baseName || !*baseName) {
  627.         reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::UnspecifiedBase);
  628.         throw TraverseSchema::InvalidComplexTypeInfo;
  629.     }
  630.     const XMLCh* prefix = getPrefix(baseName);
  631.     const XMLCh* localPart = getLocalPart(baseName);
  632.     const XMLCh* uri = resolvePrefixToURI(simpleContent, prefix);
  633.     DatatypeValidator* baseValidator = getDatatypeValidator(uri, localPart);
  634.     if (baseValidator != 0) {
  635.         // check that the simpleType does not preclude derivation by extension
  636.         if ((baseValidator->getFinalSet() & SchemaSymbols::XSD_EXTENSION) == typeInfo->getDerivedBy()) {
  637.             reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::DisallowedSimpleTypeExtension,
  638.                               baseName, typeName);
  639.             throw TraverseSchema::InvalidComplexTypeInfo;
  640.         }
  641.         typeInfo->setBaseComplexTypeInfo(0);
  642.         typeInfo->setBaseDatatypeValidator(baseValidator);
  643.     }
  644.     else {
  645.         // check for 'anyType'
  646.         if (XMLString::equals(uri, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)
  647.             && XMLString::equals(localPart, SchemaSymbols::fgATTVAL_ANYTYPE)) {
  648.             reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContentBase, baseName);
  649.             throw TraverseSchema::InvalidComplexTypeInfo;
  650.         }
  651.         processBaseTypeInfo(simpleContent, baseName, localPart, uri, typeInfo);
  652.     }
  653.     // check that the base isn't a complex type with complex content
  654.     // and that derivation method is not included in 'final'
  655.     ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
  656.     bool simpleTypeRequired = false;
  657.     if (baseTypeInfo) {
  658.         if (baseTypeInfo->getContentType() != SchemaElementDecl::Simple) {
  659.             // Schema Errata: E1-27
  660.             if (typeInfo->getDerivedBy() == SchemaSymbols::XSD_RESTRICTION
  661.                 && ((baseTypeInfo->getContentType() == SchemaElementDecl::Mixed_Simple
  662.                     || baseTypeInfo->getContentType() == SchemaElementDecl::Mixed_Complex)
  663.                     && emptiableParticle(baseTypeInfo->getContentSpec()))) {
  664.                 simpleTypeRequired = true;
  665.             }
  666.             else {
  667.                 reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContentBase, baseName);
  668.                 throw TraverseSchema::InvalidComplexTypeInfo;
  669.             }
  670.         }
  671.         if ((baseTypeInfo->getFinalSet() & typeInfo->getDerivedBy()) != 0) {
  672.             reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivation, baseName);
  673.             throw TraverseSchema::InvalidComplexTypeInfo;
  674.         }
  675.     }
  676.     // -----------------------------------------------------------------------
  677.     // Process the content of the derivation
  678.     // -----------------------------------------------------------------------
  679.     //Skip over any annotations in the restriction or extension elements
  680.     DOMElement* content = checkContent(simpleContent, XUtil::getFirstChildElement(simpleContent), true);
  681.     if (typeInfo->getDerivedBy() == SchemaSymbols::XSD_RESTRICTION) {
  682.         //Schema Spec: 5.11: Complex Type Definition Properties Correct: 2
  683.         if (typeInfo->getBaseDatatypeValidator() != 0) {
  684.             reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidComplexTypeBase, baseName);
  685.             throw TraverseSchema::InvalidComplexTypeInfo;
  686.         }
  687.         else {
  688.            typeInfo->setBaseDatatypeValidator(baseTypeInfo->getDatatypeValidator());
  689.         }
  690.         if (content != 0) {
  691.             // ---------------------------------------------------------------
  692.             // There may be a simple type definition in the restriction
  693.             // element. The data type validator will be based on it, if
  694.             // specified
  695.             // ---------------------------------------------------------------
  696.             if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) {
  697.                 DatatypeValidator* simpleTypeDV = traverseSimpleTypeDecl(content, false);
  698.                 if (simpleTypeDV) {
  699.                     // Check that the simpleType validator is validly derived
  700.                     // from base
  701.                     DatatypeValidator* baseDV = typeInfo->getBaseDatatypeValidator();
  702.                     if (baseDV  && !baseDV->isSubstitutableBy(simpleTypeDV)) {
  703.                         reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::InvalidContentRestriction);
  704.                         throw TraverseSchema::InvalidComplexTypeInfo;
  705.                     }
  706.                     typeInfo->setBaseDatatypeValidator(simpleTypeDV);
  707.                     content = XUtil::getNextSiblingElement(content);
  708.                 }
  709.                 else {
  710.                     throw TraverseSchema::InvalidComplexTypeInfo;
  711.                 }
  712.             }
  713.             // Schema Errata E1-27
  714.             // Complex Type Definition Restriction OK: 2.2
  715.             else if (simpleTypeRequired) {
  716.                 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::CT_SimpleTypeChildRequired);
  717.                 throw TraverseSchema::InvalidComplexTypeInfo;
  718.             }
  719.             // ---------------------------------------------------------------
  720.             // Build up the facet info
  721.             // ---------------------------------------------------------------
  722.             RefHashTableOf<KVStringPair>*  facets = 0;
  723.             RefArrayVectorOf<XMLCh>*       enums = 0;
  724.             XMLBuffer                      pattern(128, fMemoryManager);
  725.             XMLCh                          fixedFlagStr[16];
  726.             unsigned int                   fixedFlag = 0;
  727.             unsigned short                 scope = 0;
  728.             bool                           isFirstPattern = true;
  729.             while (content != 0) {
  730.                 const XMLCh* facetName = content->getLocalName();
  731.                 // if not a valid facet, break from the loop
  732.                 try {
  733.                     scope = fAttributeCheck.getFacetId(facetName);
  734.                 }
  735.                 catch(...) {
  736.                     break;
  737.                 }
  738.                 if (content->getNodeType() == DOMNode::ELEMENT_NODE) {
  739.                     fAttributeCheck.checkAttributes(content, scope, this);
  740.                     const XMLCh* attValue = content->getAttribute(SchemaSymbols::fgATT_VALUE);
  741.                     if (facets == 0) {
  742.                         facets = new (fMemoryManager) RefHashTableOf<KVStringPair>(29, true, fMemoryManager);
  743.                     }
  744.                     if (XMLString::equals(facetName, SchemaSymbols::fgELT_ENUMERATION)) {
  745.                         if (!enums) {
  746.                             enums = new (fMemoryManager) RefArrayVectorOf<XMLCh>(8, true, fMemoryManager);
  747.                         }
  748.                         enums->addElement(XMLString::replicate(attValue, fMemoryManager));
  749.                     }
  750.                     else if (XMLString::equals(facetName, SchemaSymbols::fgELT_PATTERN)) {
  751.                         if (isFirstPattern) { // fBuffer.isEmpty() - overhead call
  752.                             isFirstPattern = false;
  753.                             pattern.set(attValue);
  754.                         }
  755.                         else { //datatypes: 5.2.4 pattern
  756.                             pattern.append(chPipe);
  757.                             pattern.append(attValue);
  758.                         }
  759.                     }
  760.                     else {
  761.                         if (facets->containsKey(facetName)) {
  762.                             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateFacet, facetName);
  763.                         }
  764.                         else {
  765.                             const XMLCh* facetNameStr =
  766.                                 fStringPool->getValueForId(fStringPool->addOrFind(facetName));
  767.                             facets->put((void*) facetNameStr, new (fMemoryManager) KVStringPair(facetNameStr, attValue, fMemoryManager));
  768.                             checkFixedFacet(content, facetNameStr, typeInfo->getBaseDatatypeValidator(), fixedFlag);
  769.                         }
  770.                     }
  771.                 }
  772.                 content = XUtil::getNextSiblingElement(content);
  773.             }
  774.             if (facets) {
  775.                 if (!pattern.isEmpty()) {
  776.                     facets->put
  777.                     (
  778.                         (void*) SchemaSymbols::fgELT_PATTERN,
  779.                         new (fMemoryManager) KVStringPair
  780.                             (
  781.                                 SchemaSymbols::fgELT_PATTERN,
  782.                                 pattern.getRawBuffer()
  783.                             )
  784.                     );
  785.                 }
  786.                 if (fixedFlag) {
  787.                     XMLString::binToText(fixedFlag, fixedFlagStr, 15, 10);
  788.                     facets->put((void*) SchemaSymbols::fgATT_FIXED,
  789.                         new (fMemoryManager) KVStringPair(SchemaSymbols::fgATT_FIXED, fixedFlagStr, fMemoryManager));
  790.                 }
  791.                 try {
  792.                     typeInfo->setDatatypeValidator
  793.                     (
  794.                         fDatatypeRegistry->createDatatypeValidator
  795.                         (
  796.                             qualifiedName,
  797.                             typeInfo->getBaseDatatypeValidator(),
  798.                             facets, enums, false, 0
  799.                         )
  800.                     );
  801.                 }
  802.                 catch (const XMLException& excep) {
  803.                     reportSchemaError(simpleContent, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  804.                 }
  805.                 catch(...) {
  806.                     reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::DatatypeValidatorCreationError, typeName);
  807.                 }
  808.             }
  809.             else {
  810.                 typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator());
  811.             }
  812.         }
  813.         else {
  814.             // Schema Errata E1-27
  815.             // Complex Type Definition Restriction OK: 2.2
  816.             if (simpleTypeRequired) {
  817.                 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::CT_SimpleTypeChildRequired);
  818.                 throw TraverseSchema::InvalidComplexTypeInfo;
  819.             }
  820.             typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator());
  821.         }
  822.     } // end RESTRICTION
  823.     else { // EXTENSION
  824.         ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
  825.         if (baseTypeInfo!= 0) {
  826.             typeInfo->setBaseDatatypeValidator(baseTypeInfo->getDatatypeValidator());
  827.         }
  828.         typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator());
  829.     }
  830.     // -----------------------------------------------------------------------
  831.     // Process attributes if any
  832.     // -----------------------------------------------------------------------
  833.     processAttributes(simpleContent, content, baseName, localPart, uri, typeInfo);
  834.     if (XUtil::getNextSiblingElement(simpleContent) != 0) {
  835.         reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInSimpleContent);
  836.     }
  837. } // End of function traverseSimpleContentDecl
  838. /**
  839.   * Traverse complexContent Declaration
  840.   *
  841.   *   <complexContent
  842.   *     id = ID
  843.   *     mixed = boolean
  844.   *     {any attributes with non-schema namespace...}>
  845.   *
  846.   *     Content: (annotation? , (restriction | extension))
  847.   *   </complexContent>
  848.   *
  849.   *   <restriction
  850.   *     base = QNAME
  851.   *     id = ID
  852.   *     {any attributes with non-schema namespace...}>
  853.   *
  854.   *     Content: (annotation? , (group | all | choice | sequence)?,
  855.   *              ((attribute | attributeGroup)* , anyAttribute?))
  856.   *   </restriction>
  857.   *
  858.   *   <extension
  859.   *     base = QNAME
  860.   *     id = ID
  861.   *     {any attributes with non-schema namespace...}>
  862.   *         Content: (annotation? , (group | all | choice | sequence)?,
  863.   *                  ((attribute | attributeGroup)* , anyAttribute?))
  864.   *   </extension>
  865.   */
  866. void TraverseSchema::traverseComplexContentDecl(const XMLCh* const typeName,
  867.                                                 const DOMElement* const contentDecl,
  868.                                                 ComplexTypeInfo* const typeInfo,
  869.                                                 const bool isMixed)
  870. {
  871.     // ------------------------------------------------------------------
  872.     // Check attributes
  873.     // ------------------------------------------------------------------
  874.     fAttributeCheck.checkAttributes(contentDecl, GeneralAttributeCheck::E_ComplexContent, this);
  875.     // -----------------------------------------------------------------------
  876.     // Determine whether the content is mixed, or element-only
  877.     // Setting here overrides any setting on the complex type decl
  878.     // -----------------------------------------------------------------------
  879.     const XMLCh* const mixed = getElementAttValue(contentDecl, SchemaSymbols::fgATT_MIXED);
  880.     bool mixedContent = isMixed;
  881.     if (mixed) {
  882.         if (XMLString::equals(mixed, SchemaSymbols::fgATTVAL_TRUE)
  883.             || XMLString::equals(mixed, fgValueOne)) {
  884.             mixedContent = true;
  885.         }
  886.         else if (XMLString::equals(mixed, SchemaSymbols::fgATTVAL_FALSE)
  887.                  || XMLString::equals(mixed, fgValueZero)) {
  888.             mixedContent = false;
  889.         }
  890.     }
  891.     // -----------------------------------------------------------------------
  892.     // Since the type must have complex content, set the simple type validators
  893.     // to null
  894.     // -----------------------------------------------------------------------
  895.     typeInfo->setDatatypeValidator(0);
  896.     typeInfo->setBaseDatatypeValidator(0);
  897.     DOMElement* complexContent = checkContent(contentDecl,XUtil::getFirstChildElement(contentDecl),false);
  898.     // If there are no children, return
  899.     if (complexContent == 0) {
  900.        throw TraverseSchema::InvalidComplexTypeInfo;
  901.     }
  902.     // -----------------------------------------------------------------------
  903.     // The content should be either "restriction" or "extension"
  904.     // -----------------------------------------------------------------------
  905.     const XMLCh* const complexContentName = complexContent->getLocalName();
  906.     if (XMLString::equals(complexContentName, SchemaSymbols::fgELT_RESTRICTION)) {
  907.         typeInfo->setDerivedBy(SchemaSymbols::XSD_RESTRICTION);
  908.     }
  909.     else if (XMLString::equals(complexContentName, SchemaSymbols::fgELT_EXTENSION)) {
  910.         typeInfo->setDerivedBy(SchemaSymbols::XSD_EXTENSION);
  911.     }
  912.     else {
  913.         reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidComplexContent);
  914.         throw TraverseSchema::InvalidComplexTypeInfo;
  915.     }
  916.     // -----------------------------------------------------------------------
  917.     // Handle the base type name
  918.     // -----------------------------------------------------------------------
  919.     const XMLCh* baseName = getElementAttValue(complexContent, SchemaSymbols::fgATT_BASE);
  920.     if (!baseName || !*baseName) {
  921.         reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::UnspecifiedBase);
  922.         throw TraverseSchema::InvalidComplexTypeInfo;
  923.     }
  924.     const XMLCh* prefix = getPrefix(baseName);
  925.     const XMLCh* localPart = getLocalPart(baseName);
  926.     const XMLCh* uri = resolvePrefixToURI(complexContent, prefix);
  927.     bool  isBaseAnyType = false;
  928.     // -------------------------------------------------------------
  929.     // check if the base is "anyType"
  930.     // -------------------------------------------------------------
  931.     if (XMLString::equals(uri, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) &&
  932.         XMLString::equals(localPart, SchemaSymbols::fgATTVAL_ANYTYPE)) {
  933.         isBaseAnyType = true;
  934.     }
  935.     else {
  936.         processBaseTypeInfo(complexContent, baseName, localPart, uri, typeInfo);
  937.         //Check that the base is a complex type
  938.         if (typeInfo->getBaseComplexTypeInfo() == 0)  {
  939.             reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::BaseNotComplexType);
  940.             throw TraverseSchema::InvalidComplexTypeInfo;
  941.         }
  942.     }
  943.     if (fCurrentGroupInfo) // defer processing until later
  944.         throw TraverseSchema::RecursingElement;
  945.     // -----------------------------------------------------------------------
  946.     // Process the content of the derivation
  947.     // -----------------------------------------------------------------------
  948.     //Skip over any annotations in the restriction or extension elements
  949.     DOMElement* content = checkContent(complexContent, XUtil::getFirstChildElement(complexContent), true);
  950.     processComplexContent(complexContent, typeName, content, typeInfo, baseName, localPart,
  951.                           uri, mixedContent, isBaseAnyType);
  952.     if (XUtil::getNextSiblingElement(complexContent) != 0) {
  953.         reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexContent);
  954.     }
  955. }
  956. /**
  957.   * <anyAttribute
  958.   *   id = ID
  959.   *   namespace = ((##any | ##other) | list of (anyURI | (##targetNamespace | ##local)))>
  960.   *   processContents = (lax | skip | strict) : strict
  961.   *   Content: (annotation?)
  962.   * </anyAttribute>
  963.   */
  964. SchemaAttDef* TraverseSchema::traverseAnyAttribute(const DOMElement* const elem) {
  965.     // -----------------------------------------------------------------------
  966.     // Check Attributes
  967.     // -----------------------------------------------------------------------
  968.     fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_AnyAttribute, this);
  969.     // ------------------------------------------------------------------
  970.     // First, handle any ANNOTATION declaration
  971.     // ------------------------------------------------------------------
  972.     if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
  973.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AnyAttributeContentError);
  974.     }
  975.     // ------------------------------------------------------------------
  976.     // Get attributes
  977.     // ------------------------------------------------------------------
  978.     const XMLCh* const processContents =
  979.             getElementAttValue(elem, SchemaSymbols::fgATT_PROCESSCONTENTS);
  980.     const XMLCh* const nameSpace =
  981.             getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE);
  982.     // ------------------------------------------------------------------
  983.     // Set default att type based on 'processContents' value
  984.     // ------------------------------------------------------------------
  985.     XMLAttDef::DefAttTypes attDefType = XMLAttDef::ProcessContents_Strict;
  986.     if ((!processContents || !*processContents)
  987.         || XMLString::equals(processContents, SchemaSymbols::fgATTVAL_STRICT)) {
  988.         // Do nothing - defaulted already
  989.     }
  990.     else if (XMLString::equals(processContents, SchemaSymbols::fgATTVAL_SKIP)) {
  991.         attDefType = XMLAttDef::ProcessContents_Skip;
  992.     }
  993.     else if (XMLString::equals(processContents, SchemaSymbols::fgATTVAL_LAX)) {
  994.         attDefType = XMLAttDef::ProcessContents_Lax;
  995.     }
  996.     // ------------------------------------------------------------------
  997.     // Process 'namespace' attribute
  998.     // ------------------------------------------------------------------
  999.     int uriIndex = fEmptyNamespaceURI;
  1000.     XMLAttDef::AttTypes attType = XMLAttDef::Any_Any;
  1001.     ValueVectorOf<unsigned int> namespaceList(8, fMemoryManager);
  1002.     if ((!nameSpace || !*nameSpace)
  1003.         || XMLString::equals(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDANY)) {
  1004.         // Do nothing - defaulted already
  1005.     }
  1006.     else if (XMLString::equals(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDOTHER)) {
  1007.         attType = XMLAttDef::Any_Other;
  1008.         uriIndex = fTargetNSURI;
  1009.     }
  1010.     else {
  1011.         XMLStringTokenizer tokenizer(nameSpace, fMemoryManager);
  1012.         DatatypeValidator* anyURIDV = fDatatypeRegistry->getDatatypeValidator(SchemaSymbols::fgDT_ANYURI);
  1013.         attType = XMLAttDef::Any_List;
  1014.         while (tokenizer.hasMoreTokens()) {
  1015.             const XMLCh* token = tokenizer.nextToken();
  1016.             if (XMLString::equals(token, SchemaSymbols::fgATTVAL_TWOPOUNDLOCAL)) {
  1017.                 uriIndex = fEmptyNamespaceURI;
  1018.             }
  1019.             else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_TWOPOUNDTRAGETNAMESPACE)) {
  1020.                 uriIndex = fTargetNSURI;
  1021.             }
  1022.             else {
  1023.                 try {
  1024.                     anyURIDV->validate(token);
  1025.                 }
  1026.                 catch(const XMLException& excep) {
  1027.                     reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, excep.getMessage());
  1028.                 }
  1029.                 uriIndex = fURIStringPool->addOrFind(token);
  1030.             }
  1031.             if (!namespaceList.containsElement(uriIndex)) {
  1032.                 namespaceList.addElement(uriIndex);
  1033.             }
  1034.         }
  1035.         uriIndex = fEmptyNamespaceURI;
  1036.     }
  1037.     // ------------------------------------------------------------------
  1038.     // Create wildcard attribute
  1039.     // ------------------------------------------------------------------
  1040.     SchemaAttDef* attDef = new (fMemoryManager) SchemaAttDef(XMLUni::fgZeroLenString,
  1041.                                             XMLUni::fgZeroLenString,
  1042.                                             uriIndex, attType, attDefType,
  1043.                                             fMemoryManager);
  1044.     if (namespaceList.size()) {
  1045.        attDef->setNamespaceList(&namespaceList);
  1046.     }
  1047.     return attDef;
  1048. }
  1049. /**
  1050.   * <key
  1051.   *   id = ID
  1052.   *   name = NCName
  1053.   *   Content: (annotation?, (selector, field+))
  1054.   * </key>
  1055.   */
  1056. void TraverseSchema::traverseKey(const DOMElement* const icElem,
  1057.                                  SchemaElementDecl* const elemDecl) {
  1058.     // -----------------------------------------------------------------------
  1059.     // Check Attributes
  1060.     // -----------------------------------------------------------------------
  1061.     fAttributeCheck.checkAttributes(icElem, GeneralAttributeCheck::E_Key, this);
  1062.     // -----------------------------------------------------------------------
  1063.     // Create identity constraint
  1064.     // -----------------------------------------------------------------------
  1065.     const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
  1066.     if (!name || !*name) {
  1067.         return;
  1068.     }
  1069.     if (!XMLString::isValidNCName(name)) {
  1070.         reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  1071.                           SchemaSymbols::fgELT_KEY, name);
  1072.         return;
  1073.     }
  1074.     if (!fIdentityConstraintNames) {
  1075.         fIdentityConstraintNames = new (fMemoryManager) RefHash2KeysTableOf<IdentityConstraint>(29, (bool) false, fMemoryManager);
  1076.     }
  1077.     if (fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
  1078.         reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
  1079.         return;
  1080.     }
  1081.     IC_Key* icKey = new (fMemoryManager) IC_Key(name, elemDecl->getBaseName(), fMemoryManager);
  1082.     Janitor<IC_Key> janKey(icKey);
  1083.     fIdentityConstraintNames->put((void*) name, fTargetNSURI, icKey);
  1084.     // -----------------------------------------------------------------------
  1085.     // Get selector and fields
  1086.     // -----------------------------------------------------------------------
  1087.     if (!traverseIdentityConstraint(icKey, icElem)) {
  1088.         fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
  1089.         return;
  1090.     }
  1091.     // -----------------------------------------------------------------------
  1092.     // Add key to element declaration
  1093.     // -----------------------------------------------------------------------
  1094.     elemDecl->addIdentityConstraint(icKey);
  1095.     janKey.orphan();
  1096. }
  1097. /**
  1098.   * <unique
  1099.   *   id = ID
  1100.   *   name = NCName
  1101.   *   Content: (annotation?, (selector, field+))
  1102.   * </unique>
  1103.   */
  1104. void TraverseSchema::traverseUnique(const DOMElement* const icElem,
  1105.                                     SchemaElementDecl* const elemDecl) {
  1106.     // -----------------------------------------------------------------------
  1107.     // Check Attributes
  1108.     // -----------------------------------------------------------------------
  1109.     fAttributeCheck.checkAttributes(icElem, GeneralAttributeCheck::E_Unique, this);
  1110.     // -----------------------------------------------------------------------
  1111.     // Create identity constraint
  1112.     // -----------------------------------------------------------------------
  1113.     const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
  1114.     if (!name || !*name) {
  1115.         return;
  1116.     }
  1117.     if (!XMLString::isValidNCName(name)) {
  1118.         reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  1119.                           SchemaSymbols::fgELT_UNIQUE, name);
  1120.         return;
  1121.     }
  1122.     if (!fIdentityConstraintNames) {
  1123.         fIdentityConstraintNames = new (fMemoryManager) RefHash2KeysTableOf<IdentityConstraint>(29, (bool) false, fMemoryManager);
  1124.     }
  1125.     if (fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
  1126.         reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
  1127.         return;
  1128.     }
  1129.     IC_Unique* icUnique = new (fMemoryManager) IC_Unique(name, elemDecl->getBaseName(), fMemoryManager);
  1130.     Janitor<IC_Unique> janUnique(icUnique);
  1131.     fIdentityConstraintNames->put((void*) name, fTargetNSURI, icUnique);
  1132.     // -----------------------------------------------------------------------
  1133.     // Get selector and fields
  1134.     // -----------------------------------------------------------------------
  1135.     if (!traverseIdentityConstraint(icUnique, icElem)) {
  1136.         fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
  1137.         return;
  1138.     }
  1139.     // -----------------------------------------------------------------------
  1140.     // Add identity cosntraints to element declaration
  1141.     // -----------------------------------------------------------------------
  1142.     elemDecl->addIdentityConstraint(icUnique);
  1143.     janUnique.orphan();
  1144. }
  1145. /**
  1146.   * <keyref
  1147.   *   id = ID
  1148.   *   name = NCName
  1149.   *   refer = QName
  1150.   *   Content: (annotation?, (selector, field+))
  1151.   * </keyref>
  1152.   */
  1153. void TraverseSchema::traverseKeyRef(const DOMElement* const icElem,
  1154.                                     SchemaElementDecl* const elemDecl,
  1155.                                     const unsigned int namespaceDepth) {
  1156.     // -----------------------------------------------------------------------
  1157.     // Check Attributes
  1158.     // -----------------------------------------------------------------------
  1159.     fAttributeCheck.checkAttributes(icElem, GeneralAttributeCheck::E_KeyRef, this);
  1160.     // -----------------------------------------------------------------------
  1161.     // Verify that key reference "refer" attribute is valid
  1162.     // -----------------------------------------------------------------------
  1163.     const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
  1164.     const XMLCh* refer = getElementAttValue(icElem, SchemaSymbols::fgATT_REFER);
  1165.     if ((!name || !*name) || (!refer || !*refer)) {
  1166.         return;
  1167.     }
  1168.     if (!XMLString::isValidNCName(name)) {
  1169.         reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  1170.                           SchemaSymbols::fgELT_KEYREF, name);
  1171.         return;
  1172.     }
  1173.     const XMLCh* prefix = getPrefix(refer);
  1174.     const XMLCh* localPart = getLocalPart(refer);
  1175.     const XMLCh* uriStr = resolvePrefixToURI(icElem, prefix, namespaceDepth);
  1176.     IdentityConstraint* icKey = (fIdentityConstraintNames)
  1177.         ? fIdentityConstraintNames->get(localPart, fURIStringPool->addOrFind(uriStr)) : 0;
  1178.     if (!icKey) {
  1179.         reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_KeyRefReferNotFound, name, localPart);
  1180.         return;
  1181.     }
  1182.     // -----------------------------------------------------------------------
  1183.     // Create identity constraint
  1184.     // -----------------------------------------------------------------------
  1185.     if(fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
  1186.         reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
  1187.         return;
  1188.     }
  1189.     IC_KeyRef* icKeyRef = new (fMemoryManager) IC_KeyRef(name, elemDecl->getBaseName(), icKey, fMemoryManager);
  1190.     Janitor<IC_KeyRef> janKeyRef(icKeyRef);
  1191.     fIdentityConstraintNames->put((void*) name, fTargetNSURI, icKeyRef);
  1192.     // -----------------------------------------------------------------------
  1193.     // Get selector and fields
  1194.     // -----------------------------------------------------------------------
  1195.     if (!traverseIdentityConstraint(icKeyRef, icElem)) {
  1196.         fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
  1197.         return;
  1198.     }
  1199.     // -----------------------------------------------------------------------
  1200.     // Add key reference to element decl
  1201.     // -----------------------------------------------------------------------
  1202.     if (icKeyRef->getFieldCount() != icKey->getFieldCount()) {
  1203.         fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
  1204.         reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_KeyRefCardinality,
  1205.                           name, icKey->getIdentityConstraintName());
  1206.     }
  1207.     else {
  1208.         elemDecl->addIdentityConstraint(icKeyRef);
  1209.         janKeyRef.orphan();
  1210.     }
  1211. }
  1212. bool TraverseSchema::traverseIdentityConstraint(IdentityConstraint* const ic,
  1213.                                                 const DOMElement* const icElem) {
  1214.     // ------------------------------------------------------------------
  1215.     // First, handle any ANNOTATION declaration
  1216.     // ------------------------------------------------------------------
  1217.     DOMElement* elem = checkContent(icElem, XUtil::getFirstChildElement(icElem), false);
  1218.     // ------------------------------------------------------------------
  1219.     // Get selector
  1220.     // ------------------------------------------------------------------
  1221.     if (elem == 0) {
  1222. //        reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
  1223.         return false;
  1224.     }
  1225.     if (!XMLString::equals(elem->getLocalName(), SchemaSymbols::fgELT_SELECTOR)) {
  1226.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
  1227.         return false;
  1228.     }
  1229.     fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_Selector, this);
  1230.     checkContent(icElem, XUtil::getFirstChildElement(elem), true);
  1231.     // ------------------------------------------------------------------
  1232.     // Get xpath attribute
  1233.     // ------------------------------------------------------------------
  1234.     const XMLCh* xpathExpr = getElementAttValue(elem, SchemaSymbols::fgATT_XPATH, true);
  1235.     unsigned int xpathLen = XMLString::stringLen(xpathExpr);
  1236.     if (!xpathExpr || !xpathLen) {
  1237.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_XPathExprMissing);
  1238.         return false;
  1239.     }
  1240.     fBuffer.reset();
  1241.     unsigned int startIndex = 0;
  1242.     
  1243.     while (startIndex < xpathLen) {
  1244.         if (!XMLString::startsWith(xpathExpr + startIndex, fgForwardSlash)
  1245.             && !XMLString::startsWith(xpathExpr + startIndex, fgDot)) {
  1246.             fBuffer.append(fgDotForwardSlash);
  1247.         }
  1248.         int chOffset = XMLString::indexOf(xpathExpr, chPipe, startIndex);
  1249.         if (chOffset == -1)
  1250.             break;
  1251.         fBuffer.append(xpathExpr + startIndex, chOffset + 1 - startIndex);
  1252.         startIndex = chOffset + 1;
  1253.     }
  1254.     if (startIndex < xpathLen)
  1255.         fBuffer.append(xpathExpr + startIndex);
  1256.     // ------------------------------------------------------------------
  1257.     // Parse xpath expression
  1258.     // ------------------------------------------------------------------
  1259.     try {
  1260.         XercesXPath* sXPath = new (fMemoryManager) XercesXPath(fBuffer.getRawBuffer(), fStringPool, fNamespaceScope, fEmptyNamespaceURI, true, fMemoryManager);
  1261.         IC_Selector* icSelector = new (fMemoryManager) IC_Selector(sXPath, ic);
  1262.         ic->setSelector(icSelector);
  1263.     }
  1264.     catch (const XPathException& e) {
  1265.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, e.getMessage());
  1266.         return false;
  1267.     }
  1268.     // ------------------------------------------------------------------
  1269.     // Get fields
  1270.     // ------------------------------------------------------------------
  1271.     elem = XUtil::getNextSiblingElement(elem);
  1272.     if (elem == 0) {
  1273.         reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
  1274.         return false;
  1275.     }
  1276.     while (elem != 0) {
  1277.         if (!XMLString::equals(elem->getLocalName(), SchemaSymbols::fgELT_FIELD)) {
  1278.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
  1279.         }
  1280.         else {
  1281.             // General Attribute Checking
  1282.             fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_Field, this);
  1283.             checkContent(icElem, XUtil::getFirstChildElement(elem), true);
  1284.             // xpath expression parsing
  1285.             xpathExpr = getElementAttValue(elem, SchemaSymbols::fgATT_XPATH, true);
  1286.             if (!xpathExpr || !*xpathExpr) {
  1287.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_XPathExprMissing);
  1288.                 return false;
  1289.             }
  1290.     if (XMLString::startsWith(xpathExpr, fgForwardSlash)
  1291.     || XMLString::startsWith(xpathExpr, fgDot)) {
  1292.                 fBuffer.set(xpathExpr);
  1293.             }
  1294.             else {
  1295.                 fBuffer.set(fgDotForwardSlash);
  1296.                 fBuffer.append(xpathExpr);
  1297.             }
  1298.             try {
  1299.                 XercesXPath* fieldXPath = new (fMemoryManager) XercesXPath
  1300.                 (
  1301.                     fBuffer.getRawBuffer()
  1302.                     , fStringPool
  1303.                     , fNamespaceScope
  1304.                     , fEmptyNamespaceURI
  1305.                     , false
  1306.                     , fMemoryManager
  1307.                 );
  1308.                 IC_Field* icField = new (fMemoryManager) IC_Field(fieldXPath, ic);
  1309.                 ic->addField(icField);
  1310.             }
  1311.             catch (const XPathException& e) {
  1312.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, e.getMessage());
  1313.                 return false;
  1314.             }
  1315. }
  1316.         elem = XUtil::getNextSiblingElement(elem);
  1317.     }
  1318.     if (ic->getFieldCount() == 0) {
  1319.         return false;
  1320.     }
  1321.     return true;
  1322. }
  1323. // ---------------------------------------------------------------------------
  1324. //  TraverseSchema: Helper methods
  1325. // ---------------------------------------------------------------------------
  1326. void TraverseSchema::retrieveNamespaceMapping(const DOMElement* const schemaRoot) {
  1327.     DOMNamedNodeMap* schemaEltAttrs = schemaRoot->getAttributes();
  1328.     bool seenXMLNS = false;
  1329.     int attrCount = schemaEltAttrs->getLength();
  1330.     for (int i = 0; i < attrCount; i++) {
  1331.         DOMNode* attribute = schemaEltAttrs->item(i);
  1332.         if (!attribute) {
  1333.             break;
  1334.         }
  1335.         const XMLCh* attName = attribute->getNodeName();
  1336.         // starts with 'xmlns:'
  1337.         if (XMLString::startsWith(attName, fgXMLNS_Str)) {
  1338.             int offsetIndex = XMLString::indexOf(attName, chColon);
  1339.             const XMLCh* attValue = attribute->getNodeValue();
  1340.             fNamespaceScope->addPrefix(attName + offsetIndex + 1, fURIStringPool->addOrFind(attValue));
  1341.         }
  1342.         else if (XMLString::equals(attName, XMLUni::fgXMLNSString)) { // == 'xmlns'
  1343.             const XMLCh* attValue = attribute->getNodeValue();
  1344.             fNamespaceScope->addPrefix(XMLUni::fgZeroLenString, fURIStringPool->addOrFind(attValue));
  1345.             seenXMLNS = true;
  1346.         }
  1347.     } // end for
  1348.     if (!seenXMLNS && (!fTargetNSURIString || !*fTargetNSURIString)) {
  1349.         fNamespaceScope->addPrefix(XMLUni::fgZeroLenString, fEmptyNamespaceURI);
  1350.     }
  1351.     // Add mapping for xml prefix
  1352.     fNamespaceScope->addPrefix(XMLUni::fgXMLString, fURIStringPool->addOrFind(XMLUni::fgXMLURIName));
  1353. }
  1354. void TraverseSchema::processChildren(const DOMElement* const root) {
  1355.     // process <redefine>, <include> and <import> info items.
  1356.     DOMElement* child = XUtil::getFirstChildElement(root);
  1357.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  1358.         const XMLCh* name = child->getLocalName();
  1359.         if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) {
  1360.             traverseAnnotationDecl(child, true);
  1361.         }
  1362.         else if (XMLString::equals(name, SchemaSymbols::fgELT_INCLUDE)) {
  1363.             traverseInclude(child);
  1364.         }
  1365.         else if (XMLString::equals(name, SchemaSymbols::fgELT_IMPORT)) {
  1366.             traverseImport(child);
  1367.         }
  1368.         else if (XMLString::equals(name, SchemaSymbols::fgELT_REDEFINE)) {
  1369.             traverseRedefine(child);
  1370.         }
  1371.         else
  1372.             break;
  1373.     }
  1374.     // child refers to the first info item which is not <annotation> or
  1375.     // one of the schema inclusion/importation declarations.
  1376.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  1377.         const XMLCh* name = child->getLocalName();
  1378.         const XMLCh* typeName = getElementAttValue(child, SchemaSymbols::fgATT_NAME);
  1379.         int fullNameId = 0;
  1380.         if (typeName) {
  1381.             fBuffer.set(fTargetNSURIString);
  1382.             fBuffer.append(chComma);
  1383.             fBuffer.append(typeName);
  1384.             fullNameId = fStringPool->addOrFind(fBuffer.getRawBuffer());
  1385.         }
  1386.         if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) {
  1387.             traverseAnnotationDecl(child, true);
  1388.         }
  1389.         else if (XMLString::equals(name, SchemaSymbols::fgELT_SIMPLETYPE)) {
  1390.             if (typeName && *typeName) {
  1391.                 if (fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->containsElement(fullNameId)
  1392.                     || fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->containsElement(fullNameId)) {
  1393.                     reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
  1394.                                       SchemaSymbols::fgELT_SIMPLETYPE, typeName, SchemaSymbols::fgELT_COMPLEXTYPE);
  1395.                     continue;
  1396.                 }
  1397.                 else {
  1398.                     fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->addElement(fullNameId);
  1399.                 }
  1400.             }
  1401.             traverseSimpleTypeDecl(child);
  1402.         }
  1403.         else if (XMLString::equals(name, SchemaSymbols::fgELT_COMPLEXTYPE)) {
  1404.             if (typeName && *typeName) {
  1405.                 if (fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->containsElement(fullNameId)
  1406.                     || fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->containsElement(fullNameId)) {
  1407.                     reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
  1408.                                       SchemaSymbols::fgELT_COMPLEXTYPE, typeName, SchemaSymbols::fgELT_SIMPLETYPE);
  1409.                     continue;
  1410.                 }
  1411.                 else {
  1412.                     fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->addElement(fullNameId);
  1413.                 }
  1414.             }
  1415.             traverseComplexTypeDecl(child);
  1416.         }
  1417.         else if (XMLString::equals(name, SchemaSymbols::fgELT_ELEMENT)) {
  1418.             if (typeName && *typeName) {
  1419.                 if (fGlobalDeclarations[ENUM_ELT_ELEMENT]->containsElement(fullNameId)) {
  1420.                     reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
  1421.                                       SchemaSymbols::fgELT_ELEMENT, typeName);
  1422.                     continue;
  1423.                 }
  1424.                 else {
  1425.                     fGlobalDeclarations[ENUM_ELT_ELEMENT]->addElement(fullNameId);
  1426.                 }
  1427.             }
  1428.             QName* elmQName = traverseElementDecl(child, true);
  1429.             delete elmQName;
  1430.         }
  1431.         else if (XMLString::equals(name, SchemaSymbols::fgELT_ATTRIBUTEGROUP)) {
  1432.             if (typeName && *typeName) {
  1433.                 if (fGlobalDeclarations[ENUM_ELT_ATTRIBUTEGROUP]->containsElement(fullNameId)) {
  1434.                     reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
  1435.                                       SchemaSymbols::fgELT_ATTRIBUTEGROUP, typeName);
  1436.                     continue;
  1437.                 }
  1438.                 else {
  1439.                     fGlobalDeclarations[ENUM_ELT_ATTRIBUTEGROUP]->addElement(fullNameId);
  1440.                 }
  1441.             }
  1442.             if (!typeName || !fAttGroupRegistry->containsKey(typeName)) {
  1443.                 traverseAttributeGroupDecl(child, 0, true);
  1444.             }
  1445.         }
  1446.         else if (XMLString::equals(name, SchemaSymbols::fgELT_ATTRIBUTE)) {
  1447.             if (typeName && *typeName) {
  1448.                 if (fGlobalDeclarations[ENUM_ELT_ATTRIBUTE]->containsElement(fullNameId)) {
  1449.                     reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, typeName);
  1450.                     continue;
  1451.                 }
  1452.                 else {
  1453.                     fGlobalDeclarations[ENUM_ELT_ATTRIBUTE]->addElement(fullNameId);
  1454.                 }
  1455.             }
  1456.             if (!typeName || !fAttributeDeclRegistry->containsKey(typeName)) {
  1457.                 traverseAttributeDecl( child, 0, true);
  1458.             }
  1459.         }
  1460.         else if (XMLString::equals(name, SchemaSymbols::fgELT_GROUP)) {
  1461.             if (typeName && *typeName) {
  1462.                 if (fGlobalDeclarations[ENUM_ELT_GROUP]->containsElement(fullNameId)) {
  1463.                     reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
  1464.                                       SchemaSymbols::fgELT_GROUP, typeName);
  1465.                     continue;
  1466.                 }
  1467.                 else {
  1468.                     fGlobalDeclarations[ENUM_ELT_GROUP]->addElement(fullNameId);
  1469.                 }
  1470.             }
  1471.             if (!typeName || !fGroupRegistry->containsKey(fBuffer.getRawBuffer())) {
  1472.                 traverseGroupDecl(child);
  1473.             }
  1474.         }
  1475.         else if (XMLString::equals(name, SchemaSymbols::fgELT_NOTATION)) {
  1476.             traverseNotationDecl(child);
  1477.         }
  1478.         else {
  1479.             reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::SchemaElementContentError);
  1480.         }
  1481.     } // for each child node
  1482.     // Handle recursing elements - if any
  1483.     ValueVectorOf<const DOMElement*>* recursingAnonTypes = fSchemaInfo->getRecursingAnonTypes();
  1484.     if (recursingAnonTypes) {
  1485.         ValueVectorOf<const XMLCh*>* recursingTypeNames = fSchemaInfo->getRecursingTypeNames();
  1486.         unsigned int recurseSize = recursingAnonTypes->size();
  1487.         for (unsigned int i=0; i < recurseSize; i++) {
  1488.             traverseComplexTypeDecl(recursingAnonTypes->elementAt(i), false,
  1489.                                     recursingTypeNames->elementAt(i));
  1490.         }
  1491.         recursingAnonTypes->removeAllElements();
  1492.         recursingTypeNames->removeAllElements();
  1493.     }
  1494. }
  1495. void TraverseSchema::preprocessChildren(const DOMElement* const root) {
  1496.     // process <redefine>, <include> and <import> info items.
  1497.     DOMElement* child = XUtil::getFirstChildElement(root);
  1498.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  1499.         const XMLCh* name = child->getLocalName();
  1500.         if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) {
  1501.             continue;
  1502.         }
  1503.         else if (XMLString::equals(name, SchemaSymbols::fgELT_INCLUDE)) {
  1504.             preprocessInclude(child);
  1505.         }
  1506.         else if (XMLString::equals(name, SchemaSymbols::fgELT_IMPORT)) {
  1507.             preprocessImport(child);
  1508.         }
  1509.         else if (XMLString::equals(name, SchemaSymbols::fgELT_REDEFINE)) {
  1510.             preprocessRedefine(child);
  1511.         }
  1512.         else
  1513.             break;
  1514.     }
  1515. }
  1516. DOMElement* TraverseSchema::checkContent(const DOMElement* const rootElem,
  1517.                                            DOMElement* const contentElem,
  1518.                                            const bool isEmpty) {
  1519.     DOMElement* content = contentElem;
  1520.     const XMLCh* name = getElementAttValue(rootElem,SchemaSymbols::fgATT_NAME);
  1521.     if (!content) {
  1522.        if (!isEmpty) {
  1523.            reportSchemaError(rootElem, XMLUni::fgXMLErrDomain, XMLErrs::ContentError, name);
  1524.        }
  1525.        return 0;
  1526.     }
  1527.     if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ANNOTATION)) {
  1528.         traverseAnnotationDecl(content);
  1529.         content = XUtil::getNextSiblingElement(content);
  1530.         if (!content) { // must be followed by content
  1531.             if (!isEmpty) {
  1532.                 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ContentError, name);
  1533.             }
  1534.             return 0;
  1535.         }
  1536.         if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ANNOTATION)) {
  1537.             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AnnotationError, name);
  1538.             return 0;
  1539.         }
  1540.     }
  1541.     return content;
  1542. }
  1543. DatatypeValidator*
  1544. TraverseSchema::getDatatypeValidator(const XMLCh* const uriStr,
  1545.                                      const XMLCh* const localPartStr) {
  1546.     DatatypeValidator* dv = 0;
  1547.     if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
  1548.         dv = fDatatypeRegistry->getDatatypeValidator(localPartStr);
  1549.     }
  1550.     else {
  1551.         fBuffer.set(uriStr);
  1552.         fBuffer.append(chComma);
  1553.         fBuffer.append(localPartStr);
  1554.         if ((uriStr && *uriStr) && !XMLString::equals(uriStr, fTargetNSURIString)) {
  1555.             Grammar* grammar = fGrammarResolver->getGrammar(uriStr);
  1556.             if (grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) {
  1557.                 dv = ((SchemaGrammar*) grammar)->getDatatypeRegistry()->getDatatypeValidator(fBuffer.getRawBuffer());
  1558.             }
  1559.         }
  1560.         else {
  1561.             dv = fDatatypeRegistry->getDatatypeValidator(fBuffer.getRawBuffer());
  1562.         }
  1563.     }
  1564.     return dv;
  1565. }
  1566. DatatypeValidator*
  1567. TraverseSchema::checkForSimpleTypeValidator(const DOMElement* const content,
  1568.                                             int baseRefContext) {
  1569.     DatatypeValidator* baseValidator = traverseSimpleTypeDecl(content, false, baseRefContext);
  1570.     if (!baseValidator) {
  1571.         const XMLCh* name = getElementAttValue(content,SchemaSymbols::fgATT_NAME);
  1572.         reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::UnknownSimpleType, name);
  1573.     }
  1574.     return baseValidator;
  1575. }
  1576. ComplexTypeInfo*
  1577. TraverseSchema::checkForComplexTypeInfo(const DOMElement* const content) {
  1578.     int typeNameIndex = traverseComplexTypeDecl(content, false);
  1579.     ComplexTypeInfo* baseTypeInfo = 0;
  1580.     if (typeNameIndex != -1) {
  1581.         baseTypeInfo = fComplexTypeRegistry->get(fStringPool->getValueForId(typeNameIndex));
  1582.     }
  1583.     if (typeNameIndex == -1 || baseTypeInfo == 0) {
  1584.         const XMLCh* name = getElementAttValue(content,SchemaSymbols::fgATT_NAME);
  1585.         reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::UnknownComplexType, name);
  1586.     }
  1587.     return baseTypeInfo;
  1588. }
  1589. DatatypeValidator*
  1590. TraverseSchema::findDTValidator(const DOMElement* const elem,
  1591.                                 const XMLCh* const derivedTypeName,
  1592.                                 const XMLCh* const baseTypeName,
  1593.                                 const int baseRefContext) {
  1594.     const XMLCh*       prefix = getPrefix(baseTypeName);
  1595.     const XMLCh*       localPart = getLocalPart(baseTypeName);
  1596.     const XMLCh*       uri = resolvePrefixToURI(elem, prefix);
  1597.     DatatypeValidator* baseValidator = getDatatypeValidator(uri, localPart);
  1598.     if (baseValidator == 0) {
  1599.         SchemaInfo* saveInfo = fSchemaInfo;
  1600.         DOMElement* baseTypeNode = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_SimpleType,
  1601.             SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
  1602.         if (baseTypeNode != 0) {
  1603.             baseValidator = traverseSimpleTypeDecl(baseTypeNode);
  1604.             // restore schema information, if necessary
  1605.             fSchemaInfo = saveInfo;
  1606.         }
  1607.     }
  1608.     if (baseValidator == 0) {
  1609.         reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::UnknownBaseDatatype, baseTypeName, derivedTypeName);
  1610.     }
  1611.     else if ((baseValidator->getFinalSet() & baseRefContext) != 0) {
  1612.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DisallowedBaseDerivation, baseTypeName);
  1613.         return 0;
  1614.     }
  1615.     return baseValidator;
  1616. }
  1617. const XMLCh* TraverseSchema::resolvePrefixToURI(const DOMElement* const elem,
  1618.                                                 const XMLCh* const prefix) {
  1619.     int nameSpaceIndex = fNamespaceScope->getNamespaceForPrefix(prefix, fSchemaInfo->getNamespaceScopeLevel());
  1620.     const XMLCh* uriStr = fURIStringPool->getValueForId(nameSpaceIndex);
  1621.     if ((!uriStr || !*uriStr) && (prefix && *prefix)) {
  1622.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix);
  1623.         return XMLUni::fgZeroLenString;
  1624.     }
  1625.     return uriStr;
  1626. }
  1627. const XMLCh* TraverseSchema::resolvePrefixToURI(const DOMElement* const elem,
  1628.                                                 const XMLCh* const prefix,
  1629.                                                 const unsigned int namespaceDepth) {
  1630.     int nameSpaceIndex = fNamespaceScope->getNamespaceForPrefix(prefix, namespaceDepth);
  1631.     const XMLCh* uriStr = fURIStringPool->getValueForId(nameSpaceIndex);
  1632.     if ((!uriStr || !*uriStr) && (prefix && *prefix)) {
  1633.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix);
  1634.         return XMLUni::fgZeroLenString;
  1635.     }
  1636.     return uriStr;
  1637. }
  1638. QName* TraverseSchema::processElementDeclRef(const DOMElement* const elem,
  1639.                                              const XMLCh* const refName) {
  1640.     DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  1641.     if (content != 0) {
  1642.         reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_ELEMENT);
  1643.     }
  1644.     const XMLCh* prefix = getPrefix(refName);
  1645.     const XMLCh* localPart = getLocalPart(refName);
  1646.     const XMLCh* uriStr = resolvePrefixToURI(elem, prefix);
  1647.     QName*       eltName = new (fMemoryManager) QName(prefix , localPart, uriStr != 0
  1648.                                        ? fURIStringPool->addOrFind(uriStr)
  1649.                                        : fEmptyNamespaceURI, fMemoryManager);
  1650.     //if from another schema, just return the element QName
  1651.     if (!XMLString::equals(uriStr, fTargetNSURIString)) {
  1652.         return eltName;
  1653.     }
  1654.     unsigned int uriID = eltName->getURI();
  1655.     SchemaElementDecl* refElemDecl = (SchemaElementDecl*)
  1656.         fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
  1657.     //if not found, traverse the top level element that is referenced
  1658.     if (!refElemDecl) {
  1659.         SchemaInfo* saveInfo = fSchemaInfo;
  1660.         DOMElement* targetElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Element,
  1661.             SchemaSymbols::fgELT_ELEMENT, localPart, &fSchemaInfo);
  1662.         if (targetElem == 0)  {
  1663.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::RefElementNotFound, localPart);
  1664.             // REVISIT do we return 0 or what? for now we will return QName created
  1665.             return eltName;
  1666.         }
  1667.         else {
  1668.             delete eltName;
  1669.             eltName = traverseElementDecl(targetElem, true);
  1670.             refElemDecl = (SchemaElementDecl*)
  1671.                 fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
  1672.             // restore schema information
  1673.             fSchemaInfo = saveInfo;
  1674.         }
  1675.     }
  1676.     if (refElemDecl) {
  1677.         if (fCurrentComplexType)
  1678.             fCurrentComplexType->addElement(refElemDecl);
  1679.         if (fCurrentGroupInfo)
  1680.             fCurrentGroupInfo->addElement(refElemDecl);
  1681.     }
  1682.     return eltName;
  1683. }
  1684. int TraverseSchema::parseBlockSet(const DOMElement* const elem,
  1685.                                   const int blockType, const bool isRoot) {
  1686.     const XMLCh* blockVal = (isRoot) ? getElementAttValue(elem, SchemaSymbols::fgATT_BLOCKDEFAULT)
  1687.                                      : getElementAttValue(elem, SchemaSymbols::fgATT_BLOCK);
  1688.     if (!blockVal || !*blockVal) {
  1689.         return fSchemaInfo->getBlockDefault();
  1690.     }
  1691.     int blockSet = 0;
  1692.     if (XMLString::equals(blockVal, SchemaSymbols::fgATTVAL_POUNDALL)) {
  1693.         blockSet = SchemaSymbols::XSD_EXTENSION + SchemaSymbols::XSD_RESTRICTION + SchemaSymbols::XSD_SUBSTITUTION;
  1694.         return blockSet;
  1695.     }
  1696.     XMLStringTokenizer tokenizer(blockVal, fMemoryManager);
  1697.     while (tokenizer.hasMoreTokens()) {
  1698.         XMLCh* token = tokenizer.nextToken();
  1699.         if (XMLString::equals(token, SchemaSymbols::fgATTVAL_SUBSTITUTION)
  1700. && blockType == ES_Block) {
  1701.             if ((blockSet & SchemaSymbols::XSD_SUBSTITUTION) == 0 ) {
  1702.                 blockSet += SchemaSymbols::XSD_SUBSTITUTION;
  1703.             }
  1704.             else {
  1705.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionRepeated);
  1706.             }
  1707.         }
  1708.         else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_EXTENSION)) {
  1709.             if ((blockSet & SchemaSymbols::XSD_EXTENSION) == 0) {
  1710.                 blockSet += SchemaSymbols::XSD_EXTENSION;
  1711.             }
  1712.             else {
  1713.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ExtensionRepeated);
  1714.             }
  1715.         }
  1716.         else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_RESTRICTION)) {
  1717.             if ((blockSet & SchemaSymbols::XSD_RESTRICTION) == 0 ) {
  1718.                 blockSet += SchemaSymbols::XSD_RESTRICTION;
  1719.             }
  1720.             else {
  1721.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::RestrictionRepeated);
  1722.             }
  1723.         }
  1724.         else {
  1725.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidBlockValue, blockVal);
  1726.         }
  1727.     } //end while
  1728.     return (blockSet == 0 ? fSchemaInfo->getBlockDefault() : blockSet);
  1729. }
  1730. int TraverseSchema::parseFinalSet(const DOMElement* const elem,
  1731.                                   const int finalType, const bool isRoot) {
  1732.     const XMLCh* finalVal = (isRoot) ? getElementAttValue(elem, SchemaSymbols::fgATT_FINALDEFAULT)
  1733.                                      : getElementAttValue(elem, SchemaSymbols::fgATT_FINAL);
  1734.     if (!finalVal || !*finalVal) {
  1735.         return fSchemaInfo->getFinalDefault();
  1736.     }
  1737.     int finalSet = 0;
  1738.     if (XMLString::equals(finalVal, SchemaSymbols::fgATTVAL_POUNDALL)) {
  1739.         finalSet = SchemaSymbols::XSD_RESTRICTION + SchemaSymbols::XSD_LIST +
  1740.                    SchemaSymbols::XSD_UNION + SchemaSymbols::XSD_EXTENSION;
  1741.         return finalSet;
  1742.     }
  1743.     XMLStringTokenizer tokenizer(finalVal, fMemoryManager);
  1744.     while (tokenizer.hasMoreTokens()) {
  1745.         XMLCh* token = tokenizer.nextToken();
  1746.         if (XMLString::equals(token, SchemaSymbols::fgELT_UNION)
  1747.             && finalType == S_Final) {
  1748.             if ((finalSet & SchemaSymbols::XSD_UNION) == 0) {
  1749.                 finalSet += SchemaSymbols::XSD_UNION;
  1750.             }
  1751.             else {
  1752.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::UnionRepeated);
  1753.             }
  1754.         }
  1755.         else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_EXTENSION)
  1756.                  && finalType != S_Final) {
  1757.             if ((finalSet & SchemaSymbols::XSD_EXTENSION) == 0) {
  1758.                 finalSet += SchemaSymbols::XSD_EXTENSION;
  1759.             }
  1760.             else {
  1761.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ExtensionRepeated);
  1762.             }
  1763.         }
  1764.         else if (XMLString::equals(token, SchemaSymbols::fgELT_LIST)
  1765.                  && finalType == S_Final) {
  1766.             if ((finalSet & SchemaSymbols::XSD_LIST) == 0 ) {
  1767.                 finalSet += SchemaSymbols::XSD_LIST;
  1768.             }
  1769.             else {
  1770.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ListRepeated);
  1771.             }
  1772.         }
  1773.         else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_RESTRICTION)) {
  1774.             if ((finalSet & SchemaSymbols::XSD_RESTRICTION) == 0 ) {
  1775.                 finalSet += SchemaSymbols::XSD_RESTRICTION;
  1776.             }
  1777.             else {
  1778.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::RestrictionRepeated);
  1779.             }
  1780.         }
  1781.         else {
  1782.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidFinalValue, finalVal);
  1783.         }
  1784.     } //end while
  1785.     return (finalSet == 0 ? fSchemaInfo->getFinalDefault() : finalSet);
  1786. }
  1787. const DOMElement*
  1788. TraverseSchema::checkIdentityConstraintContent(const DOMElement* const content) {
  1789.     const DOMElement* child = content;
  1790.     if (child != 0) {
  1791.         do {
  1792.             if (!isIdentityConstraintName(child->getLocalName())) {
  1793.                 break;
  1794.             }
  1795.             child = XUtil::getNextSiblingElement(child);
  1796.         } while (child != 0);
  1797.     }
  1798.     return child;
  1799. }
  1800. bool TraverseSchema::isIdentityConstraintName(const XMLCh* const name) {
  1801.     return (XMLString::equals(name, SchemaSymbols::fgELT_KEY)
  1802.             || XMLString::equals(name, SchemaSymbols::fgELT_KEYREF)
  1803.             || XMLString::equals(name, SchemaSymbols::fgELT_UNIQUE));
  1804. }
  1805. const XMLCh*
  1806. TraverseSchema::checkTypeFromAnotherSchema(const DOMElement* const elem,
  1807.    const XMLCh* const typeStr) {
  1808.     const XMLCh* prefix = getPrefix(typeStr);
  1809.     const XMLCh* typeURI = resolvePrefixToURI(elem, prefix);
  1810.     if (!XMLString::equals(typeURI, fTargetNSURIString)
  1811.         && !XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)
  1812.         && (typeURI && *typeURI)) {
  1813.         return typeURI;
  1814.     }
  1815.     return 0;
  1816. }
  1817. DatatypeValidator*
  1818. TraverseSchema::getElementTypeValidator(const DOMElement* const elem,
  1819.                                         const XMLCh* const typeStr,
  1820.                                         bool& noErrorDetected,
  1821.                                         const XMLCh* const otherSchemaURI)
  1822. {
  1823.     const XMLCh*       localPart = getLocalPart(typeStr);
  1824.     const XMLCh*       typeURI = otherSchemaURI;
  1825.     DatatypeValidator* dv = 0;
  1826.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  1827.     SchemaInfo*          saveInfo = fSchemaInfo;
  1828.     int                  saveScope = fCurrentScope;
  1829.     if (otherSchemaURI != 0) {
  1830.         // Make sure that we have an explicit import statement.
  1831.         // Clause 4 of Schema Representation Constraint:
  1832.         // http://www.w3.org/TR/xmlschema-1/#src-resolve
  1833.         unsigned int uriId = fURIStringPool->addOrFind(otherSchemaURI);
  1834.         if (!fSchemaInfo->isImportingNS(uriId)) {
  1835.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, otherSchemaURI);
  1836.             return 0;
  1837.         }
  1838.         dv = getDatatypeValidator(typeURI, localPart);
  1839.         if (dv) {
  1840.             return dv;
  1841.         }
  1842.         SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
  1843.         if (!impInfo || impInfo->getProcessed()) {
  1844.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, typeURI, localPart);
  1845.             return 0;
  1846.         }
  1847.         infoType = SchemaInfo::IMPORT;
  1848.         restoreSchemaInfo(impInfo, infoType);
  1849.     }
  1850.     else {
  1851.         const XMLCh* prefix = getPrefix(typeStr);
  1852.         typeURI = resolvePrefixToURI(elem, prefix);
  1853.         dv = getDatatypeValidator(typeURI, localPart);
  1854.     }
  1855.     if (!dv) {
  1856.         if (!XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)
  1857.             || XMLString::equals(fTargetNSURIString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
  1858.             DOMElement* typeElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_SimpleType,
  1859.                 SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
  1860.             if (typeElem) {
  1861.                 dv = traverseSimpleTypeDecl(typeElem);
  1862.             }
  1863.         }
  1864.         // restore schema information, if necessary
  1865.         if (saveInfo != fSchemaInfo) {
  1866.             restoreSchemaInfo(saveInfo, infoType, saveScope);
  1867.         }
  1868.         if (!dv) {
  1869.             noErrorDetected = false;
  1870.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, typeURI, localPart);
  1871.         }
  1872.     }
  1873.     return dv;
  1874. }
  1875. DatatypeValidator*
  1876. TraverseSchema::getAttrDatatypeValidatorNS(const DOMElement* const elem,
  1877.                                            const XMLCh* localPart,
  1878.                                            const XMLCh* typeURI)
  1879. {
  1880.     DatatypeValidator*   dv = getDatatypeValidator(typeURI, localPart);
  1881.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  1882.     SchemaInfo*          saveInfo = fSchemaInfo;
  1883.     int                  saveScope = fCurrentScope;
  1884.     if (!XMLString::equals(typeURI, fTargetNSURIString)
  1885.         && (typeURI && *typeURI)) {
  1886.         // Make sure that we have an explicit import statement.
  1887.         // Clause 4 of Schema Representation Constraint:
  1888.         // http://www.w3.org/TR/xmlschema-1/#src-resolve
  1889.         unsigned int uriId = fURIStringPool->addOrFind(typeURI);
  1890.         if (!fSchemaInfo->isImportingNS(uriId)) {
  1891.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, typeURI);
  1892.             return 0;
  1893.         }
  1894.         if (!dv) {
  1895.             SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
  1896.             if (!impInfo || impInfo->getProcessed())
  1897.                 return 0;
  1898.             infoType = SchemaInfo::IMPORT;
  1899.             restoreSchemaInfo(impInfo, infoType);
  1900.         }
  1901.     }