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

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 2001, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Id: TraverseSchema.cpp,v 1.75 2003/05/26 22:05:01 knoaman Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #include <xercesc/validators/schema/TraverseSchema.hpp>
  63. #include <xercesc/framework/XMLEntityHandler.hpp>
  64. #include <xercesc/framework/XMLValidityCodes.hpp>
  65. #include <xercesc/validators/schema/identity/IC_Key.hpp>
  66. #include <xercesc/validators/schema/identity/IC_KeyRef.hpp>
  67. #include <xercesc/validators/schema/identity/IC_Unique.hpp>
  68. #include <xercesc/validators/schema/identity/IC_Field.hpp>
  69. #include <xercesc/validators/schema/identity/IC_Selector.hpp>
  70. #include <xercesc/validators/schema/identity/XercesXPath.hpp>
  71. #include <xercesc/util/XMLStringTokenizer.hpp>
  72. #include <xercesc/validators/schema/XUtil.hpp>
  73. #include <xercesc/validators/common/GrammarResolver.hpp>
  74. #include <xercesc/internal/XMLReader.hpp>
  75. #include <xercesc/validators/schema/ComplexTypeInfo.hpp>
  76. #include <xercesc/validators/schema/NamespaceScope.hpp>
  77. #include <xercesc/validators/schema/SchemaAttDefList.hpp>
  78. #include <xercesc/internal/XMLScanner.hpp>
  79. #include <xercesc/framework/LocalFileInputSource.hpp>
  80. #include <xercesc/framework/URLInputSource.hpp>
  81. #include <xercesc/validators/schema/identity/XPathException.hpp>
  82. #include <xercesc/validators/schema/GeneralAttributeCheck.hpp>
  83. #include <xercesc/validators/schema/XercesGroupInfo.hpp>
  84. #include <xercesc/validators/schema/XercesAttGroupInfo.hpp>
  85. #include <xercesc/validators/schema/XSDLocator.hpp>
  86. #include <xercesc/validators/schema/XSDDOMParser.hpp>
  87. #include <xercesc/util/HashPtr.hpp>
  88. #include <xercesc/dom/DOMNamedNodeMap.hpp>
  89. #include <xercesc/dom/impl/XSDElementNSImpl.hpp>
  90. XERCES_CPP_NAMESPACE_BEGIN
  91. // ---------------------------------------------------------------------------
  92. //  TraverseSchema: Local declaration
  93. // ---------------------------------------------------------------------------
  94. typedef RefVectorOf<DatatypeValidator> DVRefVector;
  95. // ---------------------------------------------------------------------------
  96. //  TraverseSchema: Static member data
  97. // ---------------------------------------------------------------------------
  98. // ---------------------------------------------------------------------------
  99. //  TraverseSchema: Local const data
  100. // ---------------------------------------------------------------------------
  101. const XMLCh fgXMLNS_Str[] =
  102. {
  103.     chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chColon, chNull
  104. };
  105. const XMLCh fgAnonSNamePrefix[] =
  106. {
  107.     chLatin_S, chNull
  108. };
  109. const XMLCh fgAnonCNamePrefix[] =
  110. {
  111.     chLatin_C, chNull
  112. };
  113. const XMLCh fgUnbounded[] =
  114. {
  115.     chLatin_u, chLatin_n, chLatin_b, chLatin_o, chLatin_u, chLatin_n, chLatin_d,
  116.     chLatin_e, chLatin_d, chNull
  117. };
  118. const XMLCh fgSkip[] =
  119. {
  120.     chLatin_s, chLatin_k, chLatin_i, chLatin_p, chNull
  121. };
  122. const XMLCh fgLax[] =
  123. {
  124.     chLatin_l, chLatin_a, chLatin_x, chNull
  125. };
  126. const XMLCh fgStrict[] =
  127. {
  128.     chLatin_s, chLatin_t, chLatin_r, chLatin_i, chLatin_c, chLatin_t, chNull
  129. };
  130. const XMLCh fgValueOne[] =
  131. {
  132.     chDigit_1, chNull
  133. };
  134. const XMLCh fgValueZero[] =
  135. {
  136.     chDigit_0, chNull
  137. };
  138. const XMLCh fgForwardSlash[] =
  139. {
  140.     chForwardSlash, chNull
  141. };
  142. const XMLCh fgDot[] =
  143. {
  144.     chPeriod, chNull
  145. };
  146. const XMLCh fgDotForwardSlash[] =
  147. {
  148.     chPeriod, chForwardSlash, chNull
  149. };
  150. const XMLCh* fgIdentityConstraints[] =
  151. {
  152.     SchemaSymbols::fgELT_UNIQUE,
  153.     SchemaSymbols::fgELT_KEY,
  154.     SchemaSymbols::fgELT_KEYREF
  155. };
  156. // Flags for global declaration
  157. enum {
  158.     ENUM_ELT_SIMPLETYPE,
  159.     ENUM_ELT_COMPLEXTYPE,
  160.     ENUM_ELT_ELEMENT,
  161.     ENUM_ELT_ATTRIBUTE,
  162.     ENUM_ELT_ATTRIBUTEGROUP,
  163.     ENUM_ELT_GROUP,
  164.     ENUM_ELT_SIZE
  165. };
  166. // ---------------------------------------------------------------------------
  167. //  TraverseSchema: Constructors and Destructor
  168. // ---------------------------------------------------------------------------
  169. TraverseSchema::TraverseSchema( DOMElement* const    schemaRoot
  170.                               , XMLStringPool* const   uriStringPool
  171.                               , SchemaGrammar* const   schemaGrammar
  172.                               , GrammarResolver* const grammarResolver
  173.                               , XMLScanner* const      xmlScanner
  174.                               , const XMLCh* const     schemaURL
  175.                               , XMLEntityHandler* const  entityHandler
  176.                               , XMLErrorReporter* const errorReporter
  177.                               , MemoryManager* const    manager)
  178.     : fFullConstraintChecking(false)
  179.     , fTargetNSURI(-1)
  180.     , fEmptyNamespaceURI(-1)
  181.     , fCurrentScope(Grammar::TOP_LEVEL_SCOPE)
  182.     , fScopeCount(0)
  183.     , fAnonXSTypeCount(0)
  184.     , fCircularCheckIndex(0)
  185.     , fTargetNSURIString(0)
  186.     , fDatatypeRegistry(0)
  187.     , fGrammarResolver(grammarResolver)
  188.     , fSchemaGrammar(schemaGrammar)
  189.     , fEntityHandler(entityHandler)
  190.     , fErrorReporter(errorReporter)
  191.     , fURIStringPool(uriStringPool)
  192.     , fStringPool(0)
  193.     , fBuffer(1023, manager)
  194.     , fScanner(xmlScanner)
  195.     , fNamespaceScope(0)
  196.     , fAttributeDeclRegistry(0)
  197.     , fComplexTypeRegistry(0)
  198.     , fGroupRegistry(0)
  199.     , fAttGroupRegistry(0)
  200.     , fSchemaInfoList(0)
  201.     , fSchemaInfo(0)
  202.     , fCurrentGroupInfo(0)
  203.     , fCurrentAttGroupInfo(0)
  204.     , fCurrentComplexType(0)
  205.     , fCurrentTypeNameStack(0)
  206.     , fCurrentGroupStack(0)
  207.     , fIC_NamespaceDepth(0)
  208.     , fIC_Elements(0)
  209.     , fDeclStack(0)
  210.     , fGlobalDeclarations(0)
  211.     , fNotationRegistry(0)
  212.     , fRedefineComponents(0)
  213.     , fIdentityConstraintNames(0)
  214.     , fValidSubstitutionGroups(0)
  215.     , fIC_NodeListNS(0)
  216.     , fIC_ElementsNS(0)
  217.     , fIC_NamespaceDepthNS(0)
  218.     , fParser(0)
  219.     , fPreprocessedNodes(0)
  220.     , fLocator(0)
  221.     , fMemoryManager(manager)
  222.     , fAttributeCheck(manager)
  223. {
  224.     try {
  225.         if (fGrammarResolver && schemaRoot && fURIStringPool) {
  226.             init();
  227.             preprocessSchema(schemaRoot, schemaURL);
  228.             doTraverseSchema(schemaRoot);
  229.         }
  230.     }
  231.     catch(...) {
  232.         cleanUp();
  233.         throw;
  234.     }
  235. }
  236. TraverseSchema::~TraverseSchema()
  237. {
  238.    cleanUp();
  239. }
  240. // ---------------------------------------------------------------------------
  241. //  TraverseSchema: Traversal methods
  242. // ---------------------------------------------------------------------------
  243. void TraverseSchema::doTraverseSchema(const DOMElement* const schemaRoot) {
  244.     // process children nodes
  245.     processChildren(schemaRoot);
  246.     // Handle identity constraints - keyref
  247.     if (fIC_ElementsNS && fIC_ElementsNS->containsKey(fTargetNSURIString)) {
  248.         fIC_Elements = fIC_ElementsNS->get(fTargetNSURIString);
  249.         fIC_NamespaceDepth = fIC_NamespaceDepthNS->get(fTargetNSURIString);
  250.         unsigned int icListSize = fIC_Elements->size();
  251.         for (unsigned int i=0; i < icListSize; i++) {
  252.             SchemaElementDecl* curElem = fIC_Elements->elementAt(i);
  253.             ValueVectorOf<DOMElement*>* icNodes =  fIC_NodeListNS->get(curElem);
  254.             unsigned int icNodesSize = icNodes->size();
  255.             unsigned int scopeDepth = fIC_NamespaceDepth->elementAt(i);
  256.             for (unsigned int j = 0; j < icNodesSize; j++) {
  257.                 traverseKeyRef(icNodes->elementAt(j), curElem, scopeDepth);
  258.             }
  259.         }
  260.     }
  261.     fSchemaInfo->setProcessed();
  262. }
  263. void TraverseSchema::preprocessSchema(DOMElement* const schemaRoot,
  264.                                       const XMLCh* const schemaURL) {
  265.     // Make sure namespace binding is defaulted
  266.     const XMLCh* rootPrefix = schemaRoot->getPrefix();
  267.     if (rootPrefix == 0 || !*rootPrefix) {
  268. const XMLCh* xmlnsStr = schemaRoot->getAttribute(XMLUni::fgXMLNSString);
  269.         if (!xmlnsStr || !*xmlnsStr) {
  270.             schemaRoot->setAttribute(XMLUni::fgXMLNSString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
  271.         }
  272.     }
  273.     // Set schemaGrammar data and add it to GrammarResolver
  274.     // For complex type registry, attribute decl registry , group/attGroup
  275.     // and namespace mapping, needs to check whether the passed in
  276.     // Grammar was a newly instantiated one.
  277.     fComplexTypeRegistry = fSchemaGrammar->getComplexTypeRegistry();
  278.     if (fComplexTypeRegistry == 0 ) {
  279.         fComplexTypeRegistry = new (fMemoryManager) RefHashTableOf<ComplexTypeInfo>(29, fMemoryManager);
  280.         fSchemaGrammar->setComplexTypeRegistry(fComplexTypeRegistry);
  281.     }
  282.     fGroupRegistry = fSchemaGrammar->getGroupInfoRegistry();
  283.     if (fGroupRegistry == 0 ) {
  284.         fGroupRegistry = new (fMemoryManager) RefHashTableOf<XercesGroupInfo>(13, fMemoryManager);
  285.         fSchemaGrammar->setGroupInfoRegistry(fGroupRegistry);
  286.     }
  287.     fAttGroupRegistry = fSchemaGrammar->getAttGroupInfoRegistry();
  288.     if (fAttGroupRegistry == 0 ) {
  289.         fAttGroupRegistry = new (fMemoryManager) RefHashTableOf<XercesAttGroupInfo>(13, fMemoryManager);
  290.         fSchemaGrammar->setAttGroupInfoRegistry(fAttGroupRegistry);
  291.     }
  292.     fAttributeDeclRegistry = fSchemaGrammar->getAttributeDeclRegistry();
  293.     if (fAttributeDeclRegistry == 0) {
  294.         fAttributeDeclRegistry = new (fMemoryManager) RefHashTableOf<XMLAttDef>(29, fMemoryManager);
  295.         fSchemaGrammar->setAttributeDeclRegistry(fAttributeDeclRegistry);
  296.     }
  297.     fNamespaceScope = fSchemaGrammar->getNamespaceScope();
  298.     if (fNamespaceScope == 0) {
  299.         fNamespaceScope = new (fMemoryManager) NamespaceScope(fMemoryManager);
  300.         fNamespaceScope->reset(fEmptyNamespaceURI);
  301.         fSchemaGrammar->setNamespaceScope(fNamespaceScope);
  302.     }
  303.     fValidSubstitutionGroups = fSchemaGrammar->getValidSubstitutionGroups();
  304.     if (!fValidSubstitutionGroups) {
  305.         fValidSubstitutionGroups = new (fMemoryManager) RefHash2KeysTableOf<ElemVector>(29, fMemoryManager);
  306.         fSchemaGrammar->setValidSubstitutionGroups(fValidSubstitutionGroups);
  307.     }
  308.     //Retrieve the targetnamespace URI information
  309.     const XMLCh* targetNSURIStr = schemaRoot->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE);
  310.     fSchemaGrammar->setTargetNamespace(targetNSURIStr);
  311.     fScopeCount = 0;
  312.     fCurrentScope = Grammar::TOP_LEVEL_SCOPE;
  313.     fTargetNSURIString = fSchemaGrammar->getTargetNamespace();
  314.     fTargetNSURI = fURIStringPool->addOrFind(fTargetNSURIString);
  315.     fGrammarResolver->putGrammar(fTargetNSURIString, fSchemaGrammar);
  316.     fAttributeCheck.setIDRefList(fSchemaGrammar->getIDRefList());
  317.     // Save current schema info
  318.     SchemaInfo* currInfo = new (fMemoryManager) SchemaInfo(0, 0, 0, fTargetNSURI, fScopeCount,
  319.                                           fNamespaceScope->increaseDepth(),
  320.                                           XMLString::replicate(schemaURL, fMemoryManager),
  321.                                           fTargetNSURIString, schemaRoot,
  322.                                           fMemoryManager);
  323.     if (fSchemaInfo) {
  324.         fSchemaInfo->addSchemaInfo(currInfo, SchemaInfo::IMPORT);
  325.     }
  326.     fSchemaInfo = currInfo;
  327.     fSchemaInfoList->put((void*) fSchemaInfo->getCurrentSchemaURL(), fSchemaInfo->getTargetNSURI(), fSchemaInfo);
  328.     fSchemaInfo->addSchemaInfo(fSchemaInfo, SchemaInfo::INCLUDE);
  329.     traverseSchemaHeader(schemaRoot);
  330.     // preprocess chidren
  331.     preprocessChildren(schemaRoot);
  332. }
  333. void TraverseSchema::traverseSchemaHeader(const DOMElement* const schemaRoot) {
  334.     // Make sure that the root element is <xsd:schema>
  335.     if (!XMLString::equals(schemaRoot->getLocalName(), SchemaSymbols::fgELT_SCHEMA)) {
  336.         reportSchemaError(schemaRoot, XMLUni::fgXMLErrDomain, XMLErrs::InvalidXMLSchemaRoot);
  337.     }
  338.     // Make sure that the targetNamespace value is not empty string
  339.     checkForEmptyTargetNamespace(schemaRoot);
  340.     // -----------------------------------------------------------------------
  341.     // Check Attributes
  342.     // -----------------------------------------------------------------------
  343.     fAttributeCheck.checkAttributes(schemaRoot, GeneralAttributeCheck::E_Schema, this, true);
  344.     retrieveNamespaceMapping(schemaRoot);
  345.     unsigned short elemAttrDefaultQualified = 0;
  346.     if (XMLString::equals(schemaRoot->getAttribute(SchemaSymbols::fgATT_ELEMENTFORMDEFAULT),
  347.                                   SchemaSymbols::fgATTVAL_QUALIFIED)) {
  348.         elemAttrDefaultQualified |= Elem_Def_Qualified;
  349.     }
  350.     if (XMLString::equals(schemaRoot->getAttribute(SchemaSymbols::fgATT_ATTRIBUTEFORMDEFAULT),
  351.                                   SchemaSymbols::fgATTVAL_QUALIFIED)) {
  352.         elemAttrDefaultQualified |= Attr_Def_Qualified;
  353.     }
  354.     fSchemaInfo->setElemAttrDefaultQualified(elemAttrDefaultQualified);
  355.     fSchemaInfo->setBlockDefault(parseBlockSet(schemaRoot, ES_Block, true));
  356.     fSchemaInfo->setFinalDefault(parseFinalSet(schemaRoot, ECS_Final, true));
  357. }
  358. void TraverseSchema::traverseAnnotationDecl(const DOMElement* const annotationElem,
  359.                                             const bool topLevel) {
  360.     // -----------------------------------------------------------------------
  361.     // Check Attributes
  362.     // -----------------------------------------------------------------------
  363.     fAttributeCheck.checkAttributes(annotationElem, GeneralAttributeCheck::E_Annotation, this, topLevel);
  364.     for (DOMElement* child = XUtil::getFirstChildElement(annotationElem);
  365.          child != 0;
  366.          child = XUtil::getNextSiblingElement(child)) {
  367.         const XMLCh* name = child->getLocalName();
  368.         if (XMLString::equals(name, SchemaSymbols::fgELT_APPINFO)) {
  369.             fAttributeCheck.checkAttributes(child, GeneralAttributeCheck::E_Appinfo, this);
  370.         }
  371.         else if (XMLString::equals(name, SchemaSymbols::fgELT_DOCUMENTATION)) {
  372.             fAttributeCheck.checkAttributes(child, GeneralAttributeCheck::E_Documentation, this);
  373.         }
  374.         else {
  375.             reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidAnnotationContent);
  376.         }
  377.     }
  378. }
  379. /**
  380.   * Traverse include
  381.   *
  382.   *    <include
  383.   *        id = ID
  384.   *        schemaLocation = anyURI
  385.   *        {any attributes with non-schema namespace . . .}>
  386.   *        Content: (annotation?)
  387.   *    </include>
  388.   */
  389. void TraverseSchema::preprocessInclude(const DOMElement* const elem) {
  390.     // ------------------------------------------------------------------
  391.     // Check attributes
  392.     // ------------------------------------------------------------------
  393.     fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_Include, this, true);
  394.     // ------------------------------------------------------------------
  395.     // First, handle any ANNOTATION declaration
  396.     // ------------------------------------------------------------------
  397.     if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
  398.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected);
  399.     }
  400.     // ------------------------------------------------------------------
  401.     // Get 'schemaLocation' attribute
  402.     // ------------------------------------------------------------------
  403.     const XMLCh* schemaLocation = getElementAttValue(elem, SchemaSymbols::fgATT_SCHEMALOCATION);
  404.     if (!schemaLocation || !*schemaLocation) {
  405.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNoSchemaLocation, SchemaSymbols::fgELT_INCLUDE);
  406.         return;
  407.     }
  408.     // ------------------------------------------------------------------
  409.     // Resolve schema location
  410.     // ------------------------------------------------------------------
  411.     InputSource*         srcToFill = resolveSchemaLocation(schemaLocation);
  412.     Janitor<InputSource> janSrc(srcToFill);
  413.     // Nothing to do
  414.     if (!srcToFill) {
  415.         return;
  416.     }
  417.     const XMLCh* includeURL = srcToFill->getSystemId();
  418.     SchemaInfo* includeSchemaInfo = fSchemaInfoList->get(includeURL, fTargetNSURI);
  419.     if (includeSchemaInfo) {
  420.         fSchemaInfo->addSchemaInfo(includeSchemaInfo, SchemaInfo::INCLUDE);
  421.         return;
  422.     }
  423.     // ------------------------------------------------------------------
  424.     // Parse input source
  425.     // ------------------------------------------------------------------
  426.     if (!fParser)
  427.         fParser = new (fMemoryManager) XSDDOMParser;
  428.     fParser->setValidationScheme(XercesDOMParser::Val_Never);
  429.     fParser->setDoNamespaces(true);
  430.     fParser->setUserEntityHandler(fEntityHandler);
  431.     fParser->setUserErrorReporter(fErrorReporter);
  432.     // Should just issue warning if the schema is not found
  433.     const bool flag = srcToFill->getIssueFatalErrorIfNotFound();
  434.     srcToFill->setIssueFatalErrorIfNotFound(false);
  435.     fParser->parse(*srcToFill);
  436.     // Reset the InputSource
  437.     srcToFill->setIssueFatalErrorIfNotFound(flag);
  438.     if (fParser->getSawFatal() && fScanner->getExitOnFirstFatal())
  439.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError);
  440.     // ------------------------------------------------------------------
  441.     // Get root element
  442.     // ------------------------------------------------------------------
  443.     DOMDocument* document = fParser->getDocument();
  444.     if (document) {
  445.         DOMElement* root = document->getDocumentElement();
  446.         if (root) {
  447.             const XMLCh* targetNSURIString = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE);
  448.             // check to see if targetNameSpace is right
  449.             if (*targetNSURIString
  450.                 && !XMLString::equals(targetNSURIString,fTargetNSURIString)){
  451.                 reportSchemaError(root, XMLUni::fgXMLErrDomain, XMLErrs::IncludeNamespaceDifference,
  452.                                   schemaLocation, targetNSURIString);
  453.                 return;
  454.             }
  455.             // if targetNamespace is empty, change it to includ'g schema
  456.             // targetNamespace
  457.             if (!*targetNSURIString && root->getAttributeNode(XMLUni::fgXMLNSString) == 0
  458.                 && fTargetNSURI != fEmptyNamespaceURI) {
  459.                 root->setAttribute(XMLUni::fgXMLNSString, fTargetNSURIString);
  460.             }
  461.             // --------------------------------------------------------
  462.             // Update schema information with included schema
  463.             // --------------------------------------------------------
  464.             SchemaInfo* saveInfo = fSchemaInfo;
  465.             fSchemaInfo = new (fMemoryManager) SchemaInfo(0, 0, 0, fTargetNSURI, fScopeCount,
  466.                                          fNamespaceScope->increaseDepth(),
  467.                                          XMLString::replicate(includeURL, fMemoryManager),
  468.                                          fTargetNSURIString, root,
  469.                                          fMemoryManager);
  470.             fSchemaInfoList->put((void*) fSchemaInfo->getCurrentSchemaURL(),
  471.                                  fSchemaInfo->getTargetNSURI(), fSchemaInfo);
  472.             fPreprocessedNodes->put((void*) elem, fSchemaInfo);
  473.             saveInfo->addSchemaInfo(fSchemaInfo, SchemaInfo::INCLUDE);
  474.             traverseSchemaHeader(root);
  475.             preprocessChildren(root);
  476.             fSchemaInfo = saveInfo;
  477.         }
  478.     }
  479. }
  480. void TraverseSchema::traverseInclude(const DOMElement* const elem) {
  481.     SchemaInfo* includeInfo = fPreprocessedNodes->get(elem);
  482.     if (includeInfo) {
  483.         SchemaInfo* saveInfo = fSchemaInfo;
  484.         fSchemaInfo = includeInfo;
  485.         processChildren(includeInfo->getRoot());
  486.         fSchemaInfo = saveInfo;
  487.     }
  488. }
  489. /**
  490.   * Traverse import
  491.   *
  492.   *    <import
  493.   *        id = ID
  494.   *        namespace = anyURI
  495.   *        schemaLocation = anyURI
  496.   *        {any attributes with non-schema namespace . . .}>
  497.   *        Content: (annotation?)
  498.   *    </import>
  499.   */
  500. void TraverseSchema::preprocessImport(const DOMElement* const elem) {
  501.     // ------------------------------------------------------------------
  502.     // Check attributes
  503.     // ------------------------------------------------------------------
  504.     fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_Import, this, true);
  505.     // ------------------------------------------------------------------
  506.     // First, handle any ANNOTATION declaration
  507.     // ------------------------------------------------------------------
  508.     if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
  509.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected);
  510.     }
  511.     // ------------------------------------------------------------------
  512.     // Handle 'namespace' attribute
  513.     // ------------------------------------------------------------------
  514.     const XMLCh* nameSpace = getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE);
  515.     if (XMLString::equals(nameSpace, fTargetNSURIString)) {
  516.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::Import_1_1);
  517.         return;
  518.     }
  519.     if ((!nameSpace || !*nameSpace) && fTargetNSURI == fEmptyNamespaceURI) {
  520.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::Import_1_2);
  521.         return;
  522.     }
  523.     // ------------------------------------------------------------------
  524.     // Resolve namespace to a grammar
  525.     // ------------------------------------------------------------------
  526.     Grammar* aGrammar = (nameSpace) ? fGrammarResolver->getGrammar(nameSpace) : 0;
  527.     bool grammarFound = (aGrammar && (aGrammar->getGrammarType() == Grammar::SchemaGrammarType));
  528.     if (grammarFound) {
  529.         fSchemaInfo->addImportedNS(fURIStringPool->addOrFind(nameSpace));
  530.     }
  531.     // ------------------------------------------------------------------
  532.     // Get 'schemaLocation' attribute
  533.     // ------------------------------------------------------------------
  534.     const XMLCh* schemaLocation = getElementAttValue(elem, SchemaSymbols::fgATT_SCHEMALOCATION);
  535.     if (!schemaLocation || !*schemaLocation) {
  536.         return;
  537.     }
  538.     // ------------------------------------------------------------------
  539.     // Resolve schema location
  540.     // ------------------------------------------------------------------
  541.     InputSource*         srcToFill = resolveSchemaLocation(schemaLocation);
  542.     Janitor<InputSource> janSrc(srcToFill);
  543.     // Nothing to do
  544.     if (!srcToFill) {
  545.         return;
  546.     }
  547.     const XMLCh* importURL = srcToFill->getSystemId();
  548.     SchemaInfo* importSchemaInfo = 0;
  549.     if (nameSpace)
  550.         importSchemaInfo = fSchemaInfoList->get(importURL, fURIStringPool->addOrFind(nameSpace));
  551.     else
  552.         importSchemaInfo = fSchemaInfoList->get(importURL, fEmptyNamespaceURI);
  553.     if (importSchemaInfo) {
  554.         fSchemaInfo->addSchemaInfo(importSchemaInfo, SchemaInfo::IMPORT);
  555.         return;
  556.     }
  557.     if (grammarFound) {
  558.         return;
  559.     }
  560.     // ------------------------------------------------------------------
  561.     // Parse input source
  562.     // ------------------------------------------------------------------
  563.     if (!fParser)
  564.         fParser = new (fMemoryManager) XSDDOMParser;
  565.     fParser->setValidationScheme(XercesDOMParser::Val_Never);
  566.     fParser->setDoNamespaces(true);
  567.     fParser->setUserEntityHandler(fEntityHandler);
  568.     fParser->setUserErrorReporter(fErrorReporter);
  569.     // Should just issue warning if the schema is not found
  570.     const bool flag = srcToFill->getIssueFatalErrorIfNotFound();
  571.     srcToFill->setIssueFatalErrorIfNotFound(false);
  572.     fParser->parse(*srcToFill) ;
  573.     // Reset the InputSource
  574.     srcToFill->setIssueFatalErrorIfNotFound(flag);
  575.     if (fParser->getSawFatal() && fScanner->getExitOnFirstFatal())
  576.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError);
  577.     // ------------------------------------------------------------------
  578.     // Get root element
  579.     // ------------------------------------------------------------------
  580.     DOMDocument* document = fParser->getDocument();
  581.     if (document) {
  582.         DOMElement* root = document->getDocumentElement();
  583.         if (!root) {
  584.             return;
  585.         }
  586.         const XMLCh* targetNSURIString = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE);
  587.         if (!XMLString::equals(targetNSURIString, nameSpace)) {
  588.             reportSchemaError(root, XMLUni::fgXMLErrDomain, XMLErrs::ImportNamespaceDifference,
  589.                               schemaLocation, targetNSURIString, nameSpace);
  590.         }
  591.         else {
  592.             // --------------------------------------------------------
  593.             // Preprocess new schema
  594.             // --------------------------------------------------------
  595.             SchemaInfo* saveInfo = fSchemaInfo;
  596.             fSchemaGrammar = new (fMemoryManager) SchemaGrammar(fMemoryManager);
  597.             preprocessSchema(root, importURL);
  598.             fPreprocessedNodes->put((void*) elem, fSchemaInfo);
  599.             // --------------------------------------------------------
  600.             // Restore old schema information
  601.             // --------------------------------------------------------
  602.             restoreSchemaInfo(saveInfo, SchemaInfo::IMPORT);
  603.         }
  604.     }
  605. }
  606. void TraverseSchema::traverseImport(const DOMElement* const elem) {
  607.     SchemaInfo* importInfo = fPreprocessedNodes->get(elem);
  608.     if (importInfo) {
  609.         // --------------------------------------------------------
  610.         // Traverse new schema
  611.         // --------------------------------------------------------
  612.         SchemaInfo* saveInfo = fSchemaInfo;
  613.         restoreSchemaInfo(importInfo, SchemaInfo::IMPORT);
  614.         doTraverseSchema(importInfo->getRoot());
  615.         // --------------------------------------------------------
  616.         // Restore old schema information
  617.         // --------------------------------------------------------
  618.         restoreSchemaInfo(saveInfo, SchemaInfo::IMPORT);
  619.     }
  620. }
  621. /**
  622.   * Traverse redefine declaration
  623.   *
  624.   *    <redefine>
  625.   *        schemaLocation = uriReference
  626.   *        {any attributes with non-schema namespace . . .}>
  627.   *        Content: (annotation | (
  628.   *            attributeGroup | complexType | group | simpleType))*
  629.   *    </redefine>
  630.   */
  631. void TraverseSchema::preprocessRedefine(const DOMElement* const redefineElem) {
  632.     // ------------------------------------------------------------------
  633.     // Check attributes
  634.     // ------------------------------------------------------------------
  635.     fAttributeCheck.checkAttributes(redefineElem, GeneralAttributeCheck::E_Redefine, this, true);
  636.     // First, we look through the children of redefineElem. Each one will
  637.     // correspond to an element of the redefined schema that we need to
  638.     // redefine.  To do this, we rename the element of the redefined schema,
  639.     // and rework the base or ref tag of the kid we're working on to refer to
  640.     // the renamed group or derive the renamed type.  Once we've done this, we
  641.     // actually go through the schema being redefined and convert it to a
  642.     // grammar. Only then do we run through redefineDecl's kids and put them
  643.     // in the grammar.
  644.     SchemaInfo* redefiningInfo = fSchemaInfo;
  645.     if (!openRedefinedSchema(redefineElem)) {
  646.         redefiningInfo->addFailedRedefine(redefineElem);
  647.         return;
  648.     }
  649.     if (!fRedefineComponents) {
  650.         fRedefineComponents = new (fMemoryManager) RefHash2KeysTableOf<XMLCh>(13, (bool) false, fMemoryManager);
  651.     }
  652.     SchemaInfo* redefinedInfo = fSchemaInfo;
  653.     renameRedefinedComponents(redefineElem, redefiningInfo, redefinedInfo);
  654.     // Now we have to preprocess our nicely-renamed schemas.
  655.     if (fPreprocessedNodes->containsKey(redefineElem)) {
  656.         fSchemaInfo = redefinedInfo;
  657.         preprocessChildren(fSchemaInfo->getRoot());
  658.     }
  659.     fSchemaInfo = redefiningInfo;
  660. }
  661. void TraverseSchema::traverseRedefine(const DOMElement* const redefineElem) {
  662.     SchemaInfo* saveInfo = fSchemaInfo;
  663.     SchemaInfo* redefinedInfo = fPreprocessedNodes->get(redefineElem);
  664.     if (redefinedInfo) {
  665.         // Now we have to march through our nicely-renamed schemas. When
  666.         // we do these traversals other <redefine>'s may perhaps be
  667.         // encountered; we leave recursion to sort this out.
  668.         fSchemaInfo = redefinedInfo;
  669.         processChildren(fSchemaInfo->getRoot());
  670.         fSchemaInfo = saveInfo;
  671.         // Now traverse our own <redefine>
  672.         processChildren(redefineElem);
  673.     }
  674. }
  675. /**
  676.   * Traverse the Choice, Sequence declaration
  677.   *
  678.   *    <choice-sequqnce
  679.   *        id = ID
  680.   *        maxOccurs = (nonNegativeInteger | unbounded)  : 1
  681.   *        minOccurs = nonNegativeInteger : 1
  682.   *        Content: (annotation?, (element | group | choice | sequence | any)*)
  683.   *    </choice-sequence>
  684.   */
  685. ContentSpecNode*
  686. TraverseSchema::traverseChoiceSequence(const DOMElement* const elem,
  687.                                        const int modelGroupType)
  688. {
  689.     // ------------------------------------------------------------------
  690.     // Check attributes
  691.     // ------------------------------------------------------------------
  692.     fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_Sequence, this);
  693.     // ------------------------------------------------------------------
  694.     // Process contents
  695.     // ------------------------------------------------------------------
  696.     DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  697.     ContentSpecNode* left = 0;
  698.     ContentSpecNode* right = 0;
  699.     bool hadContent = false;
  700.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  701.         ContentSpecNode* contentSpecNode = 0;
  702.         bool seeParticle = false;
  703.         const XMLCh* childName = child->getLocalName();
  704.         if (XMLString::equals(childName, SchemaSymbols::fgELT_ELEMENT)) {
  705.             QName* eltQName = traverseElementDecl(child);
  706.             if (eltQName == 0) {
  707.                 continue;
  708.             }
  709.             contentSpecNode = new (fMemoryManager) ContentSpecNode
  710.             (
  711.                 eltQName
  712.                 , false
  713.                 , fMemoryManager
  714.             );
  715.             seeParticle = true;
  716.         }
  717.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_GROUP)) {
  718.             XercesGroupInfo* grpInfo = traverseGroupDecl(child, false);
  719.             if (!grpInfo) {
  720.                 continue;
  721.             }
  722.             contentSpecNode = grpInfo->getContentSpec();
  723.             if (!contentSpecNode) {
  724.                 continue;
  725.             }
  726.             if (contentSpecNode->hasAllContent()) {
  727.                 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::AllContentLimited);
  728.                 continue;
  729.             }
  730.             contentSpecNode = new (fMemoryManager) ContentSpecNode(*contentSpecNode);
  731.             seeParticle = true;
  732.         }
  733.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_CHOICE)) {
  734.             contentSpecNode = traverseChoiceSequence(child,ContentSpecNode::Choice);
  735.             seeParticle = true;
  736.         }
  737.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_SEQUENCE)) {
  738.             contentSpecNode = traverseChoiceSequence(child,ContentSpecNode::Sequence);
  739.             seeParticle = true;
  740.         }
  741.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_ANY)) {
  742.             contentSpecNode = traverseAny(child);
  743.             seeParticle = true;
  744.         }
  745.         else {
  746.             reportSchemaError(child, XMLUni::fgValidityDomain, XMLValid::GroupContentRestricted, childName);
  747.         }
  748.         if (contentSpecNode) {
  749.             hadContent = true;
  750.         }
  751.         if (seeParticle) {
  752.             checkMinMax(contentSpecNode, child, Not_All_Context);
  753.         }
  754.         if (left == 0) {
  755.             left = contentSpecNode;
  756.         }
  757.         else if (right == 0) {
  758.             right = contentSpecNode;
  759.         }
  760.         else {
  761.             left = new (fMemoryManager) ContentSpecNode
  762.             (
  763.                 (ContentSpecNode::NodeTypes) modelGroupType
  764.                 , left
  765.                 , right
  766.                 , true
  767.                 , true
  768.                 , fMemoryManager
  769.             );
  770.             right = contentSpecNode;
  771.         }
  772.     }
  773.     if (hadContent) {
  774.         left = new (fMemoryManager) ContentSpecNode
  775.         (
  776.             (ContentSpecNode::NodeTypes) modelGroupType
  777.             , left
  778.             , right
  779.             , true
  780.             , true
  781.             , fMemoryManager
  782.         );
  783.     }
  784.     return left;
  785. }
  786. /**
  787.   * Traverse SimpleType declaration:
  788.   * <simpleType
  789.   *     id = ID
  790.   *     name = NCName>
  791.   *     Content: (annotation? , ((list | restriction | union)))
  792.   * </simpleType>
  793.   *
  794.   * traverse <list>|<restriction>|<union>
  795.   */
  796. DatatypeValidator*
  797. TraverseSchema::traverseSimpleTypeDecl(const DOMElement* const childElem,
  798.                                        const bool topLevel, int baseRefContext)
  799. {
  800.     // ------------------------------------------------------------------
  801.     // Process contents
  802.     // ------------------------------------------------------------------
  803.     const XMLCh* name = getElementAttValue(childElem,SchemaSymbols::fgATT_NAME);
  804.     bool nameEmpty = (!name || !*name);
  805.     if (topLevel && nameEmpty) {
  806.         reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,
  807.                           SchemaSymbols::fgELT_SIMPLETYPE);
  808.         return 0;
  809.     }
  810.     if (nameEmpty) { // anonymous simpleType
  811.         name = genAnonTypeName(fgAnonSNamePrefix);
  812.     }
  813.     else if (!XMLString::isValidNCName(name)) {
  814.         reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  815.                           SchemaSymbols::fgELT_SIMPLETYPE, name);
  816.         return 0;
  817.     }
  818.     fBuffer.set(fTargetNSURIString);
  819.     fBuffer.append(chComma);
  820.     fBuffer.append(name);
  821.     unsigned int fullTypeNameId = fStringPool->addOrFind(fBuffer.getRawBuffer());
  822.     const XMLCh* fullName = fStringPool->getValueForId(fullTypeNameId);
  823.     //check if we have already traversed the same simpleType decl
  824.     DatatypeValidator* dv = fDatatypeRegistry->getDatatypeValidator(fullName);
  825.     if (!dv) {
  826.         // ------------------------------------------------------------------
  827.         // Check attributes
  828.         // ------------------------------------------------------------------
  829.         unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_SimpleTypeGlobal
  830.                                           : GeneralAttributeCheck::E_SimpleTypeLocal;
  831.         fAttributeCheck.checkAttributes(childElem, scope, this, topLevel);
  832.         // Circular constraint checking
  833.         if (fCurrentTypeNameStack->containsElement(fullTypeNameId)){
  834.             reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, name);
  835.             return 0;
  836.         }
  837.         fCurrentTypeNameStack->addElement(fullTypeNameId);
  838.         // Get 'final' values
  839.         int finalSet = parseFinalSet(childElem, S_Final);
  840.         // annotation?,(list|restriction|union)
  841.         DOMElement* content= checkContent(childElem,
  842.                                           XUtil::getFirstChildElement(childElem),
  843.                                           false);
  844.         if (content == 0) {
  845.             reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::EmptySimpleTypeContent);
  846.             popCurrentTypeNameStack();
  847.             return 0;
  848.         }
  849.         const XMLCh* varietyName = content->getLocalName();
  850.         // Remark: some code will be repeated in list|restriction| union but it
  851.         //         is cleaner that way
  852.         if (XMLString::equals(varietyName, SchemaSymbols::fgELT_LIST)) { //traverse List
  853.             if ((baseRefContext & SchemaSymbols::XSD_LIST) != 0) {
  854.                 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AtomicItemType);
  855.                 popCurrentTypeNameStack();
  856.                 return 0;
  857.             }
  858.             DatatypeValidator *tmpDV = traverseByList(childElem, content, name, fullName, finalSet);
  859.             if(tmpDV && nameEmpty)
  860.                 tmpDV->setAnonymous();
  861.             return tmpDV;
  862.         }
  863.         else if (XMLString::equals(varietyName, SchemaSymbols::fgELT_RESTRICTION)) { //traverse Restriction
  864.             DatatypeValidator *tmpDV = traverseByRestriction(childElem, content, name, fullName, finalSet);
  865.             if(tmpDV && nameEmpty)
  866.                 tmpDV->setAnonymous();
  867.             return tmpDV;
  868.         }
  869.         else if (XMLString::equals(varietyName, SchemaSymbols::fgELT_UNION)) { //traverse union
  870.             DatatypeValidator *tmpDV = traverseByUnion(childElem, content, name, fullName, finalSet, baseRefContext);
  871.             if(tmpDV && nameEmpty)
  872.                 tmpDV->setAnonymous();
  873.             return tmpDV;
  874.         }
  875.         else {
  876.             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::FeatureUnsupported, varietyName);
  877.             popCurrentTypeNameStack();
  878.         }
  879.     }
  880.     return dv;
  881. }
  882. /**
  883.   * Traverse ComplexType Declaration - CR Implementation.
  884.   *
  885.   *     <complexType
  886.   *        abstract = boolean
  887.   *        block = #all or (possibly empty) subset of {extension, restriction}
  888.   *        final = #all or (possibly empty) subset of {extension, restriction}
  889.   *        id = ID
  890.   *        mixed = boolean : false
  891.   *        name = NCName>
  892.   *        Content: (annotation? , (simpleContent | complexContent |
  893.   *                   ( (group | all | choice | sequence)? ,
  894.   *                   ( (attribute | attributeGroup)* , anyAttribute?))))
  895.   *     </complexType>
  896.   */
  897. int TraverseSchema::traverseComplexTypeDecl(const DOMElement* const elem,
  898.                                             const bool topLevel,
  899.                                             const XMLCh* const recursingTypeName) {
  900.     // Get the attributes of the complexType
  901.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  902.     bool isAnonymous = false;
  903.     if (!name || !*name) {
  904.         if (topLevel) {
  905.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TopLevelNoNameComplexType);
  906.             return -1;
  907.         }
  908.         if (recursingTypeName)
  909.             name = recursingTypeName;
  910.         else {
  911.             name = genAnonTypeName(fgAnonCNamePrefix);
  912.             isAnonymous = true;
  913.         }
  914.     }
  915.     if (!XMLString::isValidNCName(name)) {
  916.         //REVISIT - Should we return or continue and save type with wrong name?
  917.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  918.                           SchemaSymbols::fgELT_COMPLEXTYPE, name);
  919.         return -1;
  920.     }
  921.     // ------------------------------------------------------------------
  922.     // Check if the type has already been registered
  923.     // ------------------------------------------------------------------
  924.     fBuffer.set(fTargetNSURIString);
  925.     fBuffer.append(chComma);
  926.     fBuffer.append(name);
  927.     int typeNameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());
  928.     const XMLCh* fullName = fStringPool->getValueForId(typeNameIndex);
  929.     ComplexTypeInfo* typeInfo = 0;
  930.     if (topLevel || recursingTypeName) {
  931.         typeInfo = fComplexTypeRegistry->get(fullName);
  932.         if (typeInfo && !typeInfo->getPreprocessed()) {
  933.             return typeNameIndex;
  934.         }
  935.     }
  936.     // -----------------------------------------------------------------------
  937.     // Check Attributes
  938.     // -----------------------------------------------------------------------
  939.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_ComplexTypeGlobal
  940.                                       : GeneralAttributeCheck::E_ComplexTypeLocal;
  941.     fAttributeCheck.checkAttributes(elem, scope, this, topLevel);
  942.     // -----------------------------------------------------------------------
  943.     // Create a new instance
  944.     // -----------------------------------------------------------------------
  945.     bool preProcessFlag = (typeInfo) ? typeInfo->getPreprocessed() : false;
  946.     unsigned int previousCircularCheckIndex = fCircularCheckIndex;
  947.     int previousScope = fCurrentScope;
  948.     if (preProcessFlag) {
  949.         fCurrentScope = typeInfo->getScopeDefined();
  950.         typeInfo->setPreprocessed(false);
  951.     }
  952.     else {
  953.         // ------------------------------------------------------------------
  954.         // Register the type
  955.         // ------------------------------------------------------------------
  956.         typeInfo = new (fMemoryManager) ComplexTypeInfo(fMemoryManager);
  957.         if(isAnonymous) {
  958.             typeInfo->setAnonymous();
  959.         }
  960.         fCurrentScope = fScopeCount++;
  961.         fComplexTypeRegistry->put((void*) fullName, typeInfo);
  962.         typeInfo->setTypeName(fullName);
  963.         typeInfo->setScopeDefined(fCurrentScope);
  964.         if (fFullConstraintChecking) {
  965.             XSDLocator* aLocator = new (fMemoryManager) XSDLocator();
  966.             aLocator->setValues(fStringPool->getValueForId(fStringPool->addOrFind(fSchemaInfo->getCurrentSchemaURL())),
  967.                                 0, ((XSDElementNSImpl*) elem)->getLineNo(),
  968.                                 ((XSDElementNSImpl*) elem)->getColumnNo());
  969.             typeInfo->setLocator(aLocator);
  970.         }
  971.     }
  972.     fCurrentTypeNameStack->addElement(typeNameIndex);
  973.     ComplexTypeInfo* saveTypeInfo = fCurrentComplexType;
  974.     fCurrentComplexType = typeInfo;
  975.     // ------------------------------------------------------------------
  976.     // First, handle any ANNOTATION declaration and get next child
  977.     // ------------------------------------------------------------------
  978.     DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  979.     // ------------------------------------------------------------------
  980.     // Process the content of the complex type declaration
  981.     // ------------------------------------------------------------------
  982.     try {
  983.         const XMLCh* mixedVal = getElementAttValue(elem,SchemaSymbols::fgATT_MIXED);
  984.         bool isMixed = false;
  985.         if ((mixedVal && *mixedVal)
  986.             && (XMLString::equals(SchemaSymbols::fgATTVAL_TRUE, mixedVal)
  987.                 || XMLString::equals(fgValueOne, mixedVal))) {
  988.             isMixed = true;
  989.         }
  990.         if (child == 0) {
  991.             // EMPTY complexType with complexContent
  992.             processComplexContent(elem, name, child, typeInfo, 0,0,0, isMixed);
  993.         }
  994.         else {
  995.             const XMLCh* childName = child->getLocalName();
  996.             if (XMLString::equals(childName, SchemaSymbols::fgELT_SIMPLECONTENT)) {
  997.                 // SIMPLE CONTENT element
  998.                 traverseSimpleContentDecl(name, fullName, child, typeInfo);
  999.                 if (XUtil::getNextSiblingElement(child) != 0) {
  1000.                     reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildFollowingSimpleContent);
  1001.                 }
  1002.             }
  1003.             else if (XMLString::equals(childName, SchemaSymbols::fgELT_COMPLEXCONTENT)) {
  1004.                 // COMPLEX CONTENT element
  1005.                 traverseComplexContentDecl(name, child, typeInfo, isMixed);
  1006.                 if (XUtil::getNextSiblingElement(child) != 0) {
  1007.                     reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildFollowingConplexContent);
  1008.                 }
  1009.             }
  1010.             else if (fCurrentGroupInfo) {
  1011.                 typeInfo->setPreprocessed(true);
  1012.             }
  1013.             else {
  1014.                 // We must have ....
  1015.                 // GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes
  1016.                 // Note that it's possible that only attributes are specified.
  1017.                 processComplexContent(elem, name, child, typeInfo, 0, 0, 0, isMixed);
  1018.             }
  1019.         }
  1020.     }
  1021.     catch(const TraverseSchema::ExceptionCodes aCode) {
  1022.         if (aCode == TraverseSchema::InvalidComplexTypeInfo)
  1023.             defaultComplexTypeInfo(typeInfo);
  1024.         else if (aCode == TraverseSchema::RecursingElement)
  1025.             typeInfo->setPreprocessed();
  1026.     }
  1027.     // ------------------------------------------------------------------
  1028.     // Finish the setup of the typeInfo
  1029.     // ------------------------------------------------------------------
  1030.     if (!preProcessFlag) {
  1031.         const XMLCh* abstractAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT);
  1032.         int blockSet = parseBlockSet(elem, C_Block);
  1033.         int finalSet = parseFinalSet(elem, EC_Final);
  1034.         typeInfo->setBlockSet(blockSet);
  1035.         typeInfo->setFinalSet(finalSet);
  1036.         if ((abstractAttVal && *abstractAttVal)
  1037.             && (XMLString::equals(abstractAttVal, SchemaSymbols::fgATTVAL_TRUE)
  1038.                 || XMLString::equals(abstractAttVal, fgValueOne))) {
  1039.             typeInfo->setAbstract(true);
  1040.         }
  1041.         else {
  1042.             typeInfo->setAbstract(false);
  1043.         }
  1044.     }
  1045.     // ------------------------------------------------------------------
  1046.     // Before exiting, restore the scope, mainly for nested anonymous types
  1047.     // ------------------------------------------------------------------
  1048.     popCurrentTypeNameStack();
  1049.     fCircularCheckIndex = previousCircularCheckIndex;
  1050.     fCurrentScope = previousScope;
  1051.     fCurrentComplexType = saveTypeInfo;
  1052.     return typeNameIndex;
  1053. }
  1054. /**
  1055.   * Traverse Group Declaration.
  1056.   *
  1057.   * <group
  1058.   *         id = ID
  1059.   *         maxOccurs = string
  1060.   *         minOccurs = nonNegativeInteger
  1061.   *         name = NCName
  1062.   *         ref = QName>
  1063.   *   Content: (annotation? , (all | choice | sequence)?)
  1064.   * <group/>
  1065.   *
  1066.   */
  1067. XercesGroupInfo*
  1068. TraverseSchema::traverseGroupDecl(const DOMElement* const elem,
  1069.                                   const bool topLevel) {
  1070.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  1071.     const XMLCh* ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF);
  1072.     bool         nameEmpty = (!name || !*name);
  1073.     bool         refEmpty = (!ref || !*ref);
  1074.     if (nameEmpty && topLevel) {
  1075.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,
  1076.                           SchemaSymbols::fgELT_GROUP);
  1077.         return 0;
  1078.     }
  1079.     if (nameEmpty && refEmpty) {
  1080.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefGroup);
  1081.         return 0;
  1082.     }
  1083.     // ------------------------------------------------------------------
  1084.     // Check attributes
  1085.     // ------------------------------------------------------------------
  1086.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_GroupGlobal
  1087.                                       : GeneralAttributeCheck::E_GroupRef;
  1088.     fAttributeCheck.checkAttributes(elem, scope, this, topLevel);
  1089.     // ------------------------------------------------------------------
  1090.     // Check for annotations
  1091.     // ------------------------------------------------------------------
  1092.     DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  1093.     // ------------------------------------------------------------------
  1094.     // Handle "ref="
  1095.     // ------------------------------------------------------------------
  1096.     if (!topLevel) {
  1097.         if (refEmpty) {
  1098.             return 0;
  1099.         }
  1100.         return processGroupRef(elem, ref);
  1101.     }
  1102.     // ------------------------------------------------------------------
  1103.     // Process contents of global groups
  1104.     // ------------------------------------------------------------------
  1105.     // name must be a valid NCName
  1106.     if (!XMLString::isValidNCName(name)) {
  1107.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  1108.                           SchemaSymbols::fgELT_GROUP, name);
  1109.         return 0;
  1110.     }
  1111.     fBuffer.set(fTargetNSURIString);
  1112.     fBuffer.append(chComma);
  1113.     fBuffer.append(name);
  1114.     unsigned int nameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());
  1115.     const XMLCh* fullName = fStringPool->getValueForId(nameIndex);
  1116.     XercesGroupInfo* groupInfo = fGroupRegistry->get(fullName);
  1117.     if (groupInfo) {
  1118.         return groupInfo;
  1119.     }
  1120.     int saveScope = fCurrentScope;
  1121.     ContentSpecNode* specNode = 0;
  1122.     XercesGroupInfo* saveGroupInfo = fCurrentGroupInfo;
  1123.     groupInfo = new (fMemoryManager) XercesGroupInfo(fMemoryManager);
  1124.     fCurrentGroupStack->addElement(nameIndex);
  1125.     fCurrentGroupInfo = groupInfo;
  1126.     if (fCurrentScope == Grammar::TOP_LEVEL_SCOPE) {
  1127.         fCurrentScope = fScopeCount++;
  1128.     }
  1129.     fCurrentGroupInfo->setScope(fCurrentScope);
  1130.     if (content == 0) {
  1131.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::GroupContentError, name);
  1132.     }
  1133.     else {
  1134.         if (content->getAttributeNode(SchemaSymbols::fgATT_MINOCCURS) != 0
  1135.             || content->getAttributeNode(SchemaSymbols::fgATT_MAXOCCURS) != 0) {
  1136.             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::MinMaxOnGroupChild);
  1137.         }
  1138.         bool illegalChild = false;
  1139.         const XMLCh* childName = content->getLocalName();
  1140.         if (XMLString::equals(childName, SchemaSymbols::fgELT_SEQUENCE)) {
  1141.             specNode = traverseChoiceSequence(content, ContentSpecNode::Sequence);
  1142.         }
  1143.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_CHOICE)) {
  1144.             specNode = traverseChoiceSequence(content, ContentSpecNode::Choice);
  1145.         }
  1146.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_ALL)) {
  1147.             specNode = traverseAll(content);
  1148.         }
  1149.         else {
  1150.             illegalChild = true;
  1151.         }
  1152.         if (illegalChild || XUtil::getNextSiblingElement(content) != 0) {
  1153.             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::GroupContentError, name);
  1154.         }
  1155.     }
  1156.     // ------------------------------------------------------------------
  1157.     // Set groupInfo and pop group name from stack
  1158.     // ------------------------------------------------------------------
  1159.     unsigned int stackSize = fCurrentGroupStack->size();
  1160.     if (stackSize != 0) {
  1161.         fCurrentGroupStack->removeElementAt(stackSize - 1);
  1162.     }
  1163.     fCurrentGroupInfo->setContentSpec(specNode);
  1164.     fGroupRegistry->put((void*) fullName, fCurrentGroupInfo);
  1165.     fCurrentGroupInfo = saveGroupInfo;
  1166.     fCurrentScope = saveScope;
  1167.     if (fFullConstraintChecking) {
  1168.         XSDLocator* aLocator = new (fMemoryManager) XSDLocator();
  1169.         groupInfo->setLocator(aLocator);
  1170.         aLocator->setValues(fStringPool->getValueForId(fStringPool->addOrFind(fSchemaInfo->getCurrentSchemaURL())),
  1171.                             0, ((XSDElementNSImpl*) elem)->getLineNo(),
  1172.                             ((XSDElementNSImpl*) elem)->getColumnNo());
  1173.         if (fRedefineComponents && fRedefineComponents->get(SchemaSymbols::fgELT_GROUP, nameIndex)) {
  1174.             fBuffer.set(fullName);
  1175.             fBuffer.append(SchemaSymbols::fgRedefIdentifier);
  1176.             groupInfo->setBaseGroup(fGroupRegistry->get(fBuffer.getRawBuffer()));
  1177.         }
  1178.     }
  1179.     return groupInfo;
  1180. }
  1181. /**
  1182.   * Traverse attributeGroup Declaration.
  1183.   *
  1184.   * <attributeGroup
  1185.   *         id = ID
  1186.   *         name = NCName
  1187.   *         ref = QName>
  1188.   *   Content: (annotation? , (attribute|attributeGroup)*, anyAttribute?)
  1189.   * <attributeGroup/>
  1190.   *
  1191.   */
  1192. XercesAttGroupInfo*
  1193. TraverseSchema::traverseAttributeGroupDecl(const DOMElement* const elem,
  1194.                                            ComplexTypeInfo* const typeInfo,
  1195.                                            const bool topLevel) {
  1196.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  1197.     const XMLCh* ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF);
  1198.     bool         nameEmpty = (!name || !*name) ? true : false;
  1199.     bool         refEmpty = (!ref || !*ref) ? true : false;
  1200.     if (nameEmpty && topLevel) {
  1201.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,
  1202. SchemaSymbols::fgELT_ATTRIBUTEGROUP);
  1203.         return 0;
  1204.     }
  1205.     if (nameEmpty && refEmpty) {
  1206.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefAttGroup);
  1207.         return 0;
  1208.     }
  1209.     // ------------------------------------------------------------------
  1210.     // Check attributes
  1211.     // ------------------------------------------------------------------
  1212.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_AttributeGroupGlobal
  1213.                                       : GeneralAttributeCheck::E_AttributeGroupRef;
  1214.     fAttributeCheck.checkAttributes(elem, scope, this, topLevel);
  1215.     // ------------------------------------------------------------------
  1216.     // Handle "ref="
  1217.     // ------------------------------------------------------------------
  1218.     if (!topLevel) {
  1219.         if (refEmpty) {
  1220.             return 0;
  1221.         }
  1222.         return processAttributeGroupRef(elem, ref, typeInfo);
  1223.     }
  1224.     // ------------------------------------------------------------------
  1225.     // Handle "name="
  1226.     // ------------------------------------------------------------------
  1227.     // name must be a valid NCName
  1228.     if (!XMLString::isValidNCName(name)) {
  1229.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  1230.                           SchemaSymbols::fgELT_ATTRIBUTEGROUP, name);
  1231.         return 0;
  1232.     }
  1233.     // ------------------------------------------------------------------
  1234.     // Check for annotations
  1235.     // ------------------------------------------------------------------
  1236.     DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  1237.     // ------------------------------------------------------------------
  1238.     // Process contents of global attributeGroups
  1239.     // ------------------------------------------------------------------
  1240.     XercesAttGroupInfo* saveAttGroupInfo = fCurrentAttGroupInfo;
  1241.     XercesAttGroupInfo* attGroupInfo = new (fMemoryManager) XercesAttGroupInfo(fMemoryManager);
  1242.     fDeclStack->addElement(elem);
  1243.     fCurrentAttGroupInfo = attGroupInfo;
  1244.     for (; content !=0; content = XUtil::getNextSiblingElement(content)) {
  1245.         if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ATTRIBUTE)) {
  1246.             traverseAttributeDecl(content, typeInfo);
  1247.         }
  1248.         else if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ATTRIBUTEGROUP)) {
  1249.             traverseAttributeGroupDecl(content, typeInfo);
  1250.         }
  1251.         else {
  1252.             break;
  1253.         }
  1254.     }
  1255.     if (content != 0) {
  1256.         if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ANYATTRIBUTE)) {
  1257.             SchemaAttDef* anyAtt = traverseAnyAttribute(content);
  1258.             if (anyAtt) {
  1259.                 fCurrentAttGroupInfo->addAnyAttDef(anyAtt);
  1260.             }
  1261.             if (XUtil::getNextSiblingElement(content) != 0) {
  1262.                 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AttGroupContentError, name);
  1263.             }
  1264.         }
  1265.         else {
  1266.             reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AttGroupContentError, name);
  1267.         }
  1268.     }
  1269.     // ------------------------------------------------------------------
  1270.     // Pop declaration
  1271.     // ------------------------------------------------------------------
  1272.     fDeclStack->removeElementAt(fDeclStack->size() - 1);
  1273.     // ------------------------------------------------------------------
  1274.     // Restore old attGroupInfo
  1275.     // ------------------------------------------------------------------
  1276.     fAttGroupRegistry->put((void*) fStringPool->getValueForId(fStringPool->addOrFind(name)), attGroupInfo);
  1277.     fCurrentAttGroupInfo = saveAttGroupInfo;
  1278.     // ------------------------------------------------------------------
  1279.     // Check Attribute Derivation Restriction OK
  1280.     // ------------------------------------------------------------------
  1281.     fBuffer.set(fTargetNSURIString);
  1282.     fBuffer.append(chComma);
  1283.     fBuffer.append(name);
  1284.     unsigned int nameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());
  1285.     if (fRedefineComponents && fRedefineComponents->get(SchemaSymbols::fgELT_ATTRIBUTEGROUP, nameIndex)) {
  1286.         fBuffer.set(name);
  1287.         fBuffer.append(SchemaSymbols::fgRedefIdentifier);
  1288.         XercesAttGroupInfo* baseAttGroupInfo = fAttGroupRegistry->get(fBuffer.getRawBuffer());
  1289.         if (baseAttGroupInfo) {
  1290.             checkAttDerivationOK(elem, baseAttGroupInfo, attGroupInfo);
  1291.         }
  1292.     }
  1293.     return attGroupInfo;
  1294. }
  1295. inline XercesAttGroupInfo*
  1296. TraverseSchema::traverseAttributeGroupDeclNS(const DOMElement* const elem,
  1297.                                              const XMLCh* const uriStr,
  1298.                                              const XMLCh* const name) {
  1299.     // ------------------------------------------------------------------
  1300.     // Get grammar information
  1301.     // ------------------------------------------------------------------
  1302.     Grammar* aGrammar = fGrammarResolver->getGrammar(uriStr);
  1303.     if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
  1304.         reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
  1305.         return 0;
  1306.     }
  1307.     XercesAttGroupInfo* attGroupInfo = ((SchemaGrammar*)aGrammar)->getAttGroupInfoRegistry()->get(name);
  1308.     return attGroupInfo;
  1309. }
  1310. /**
  1311.   * Traverse Any declaration
  1312.   *
  1313.   *     <any
  1314.   *        id = ID
  1315.   *        maxOccurs = (nonNegativeInteger | unbounded)  : 1
  1316.   *        minOccurs = nonNegativeInteger : 1
  1317.   *        namespace = ((##any | ##other) | List of (anyURI |
  1318.   *                     (##targetNamespace | ##local)) )  : ##any
  1319.   *        processContents = (lax | skip | strict) : strict
  1320.   *        {any attributes with non-schema namespace . . .}>
  1321.   *        Content: (annotation?)
  1322.   *     </any>
  1323.   */
  1324. ContentSpecNode*
  1325. TraverseSchema::traverseAny(const DOMElement* const elem) {
  1326.     // -----------------------------------------------------------------------
  1327.     // Check Attributes
  1328.     // -----------------------------------------------------------------------
  1329.     fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_Any, this);
  1330.     // ------------------------------------------------------------------
  1331.     // First, handle any ANNOTATION declaration
  1332.     // ------------------------------------------------------------------
  1333.     if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
  1334.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected);
  1335.     }
  1336.     // ------------------------------------------------------------------
  1337.     // Get attributes
  1338.     // ------------------------------------------------------------------
  1339.     const XMLCh* const processContents = getElementAttValue(elem, SchemaSymbols::fgATT_PROCESSCONTENTS);
  1340.     const XMLCh* const nameSpace = getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE);
  1341.     // ------------------------------------------------------------------
  1342.     // Set default node type based on 'processContents' value
  1343.     // ------------------------------------------------------------------
  1344.     ContentSpecNode::NodeTypes anyType = ContentSpecNode::Any;
  1345.     ContentSpecNode::NodeTypes anyLocalType = ContentSpecNode::Any_NS;
  1346.     ContentSpecNode::NodeTypes anyOtherType = ContentSpecNode::Any_Other;
  1347.     if ((processContents && *processContents)
  1348.         && !XMLString::equals(processContents, fgStrict)) {
  1349.         if (XMLString::equals(processContents, fgLax)) {
  1350.             anyType = ContentSpecNode::Any_Lax;
  1351.             anyOtherType = ContentSpecNode::Any_Other_Lax;
  1352.             anyLocalType = ContentSpecNode::Any_NS_Lax;
  1353.         }
  1354.         else if (XMLString::equals(processContents, fgSkip)) {
  1355.             anyType = ContentSpecNode::Any_Skip;
  1356.             anyOtherType = ContentSpecNode::Any_Other_Skip;
  1357.             anyLocalType = ContentSpecNode::Any_NS_Skip;
  1358.         }
  1359.     }
  1360.     // ------------------------------------------------------------------
  1361.     // Process 'namespace' attribute
  1362.     // ------------------------------------------------------------------
  1363.     ContentSpecNode* retSpecNode = 0;
  1364.     if ((!nameSpace || !*nameSpace)
  1365.         || XMLString::equals(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDANY)) {
  1366.         retSpecNode = new (fMemoryManager) ContentSpecNode
  1367.         (
  1368.             new (fMemoryManager) QName
  1369.             (
  1370.                 XMLUni::fgZeroLenString
  1371.                 , XMLUni::fgZeroLenString
  1372.                 , fEmptyNamespaceURI
  1373.                 , fMemoryManager
  1374.             )
  1375.             , false
  1376.             , fMemoryManager
  1377.         );
  1378.         retSpecNode->setType(anyType);
  1379.     }
  1380.     else if (XMLString::equals(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDOTHER)) {
  1381.         retSpecNode = new (fMemoryManager) ContentSpecNode
  1382.         (
  1383.             new (fMemoryManager) QName
  1384.             (
  1385.                 XMLUni::fgZeroLenString
  1386.                 , XMLUni::fgZeroLenString
  1387.                 , fTargetNSURI, fMemoryManager
  1388.             )
  1389.             , false
  1390.             , fMemoryManager
  1391.         );
  1392.         retSpecNode->setType(anyOtherType);
  1393.     }
  1394.     else {
  1395.         BaseRefVectorOf<XMLCh>* nameSpaceTokens = XMLString::tokenizeString(nameSpace);
  1396.         ValueVectorOf<unsigned int> uriList(8, fMemoryManager);
  1397.         ContentSpecNode* firstNode = 0;
  1398.         ContentSpecNode* secondNode = 0;
  1399.         unsigned int tokensSize = nameSpaceTokens->size();
  1400.         DatatypeValidator* anyURIDV = fDatatypeRegistry->getDatatypeValidator(SchemaSymbols::fgDT_ANYURI);
  1401.         for (unsigned int i=0; i < tokensSize; i++) {
  1402.             const XMLCh* tokenElem = nameSpaceTokens->elementAt(i);
  1403.             int uriIndex = fEmptyNamespaceURI;
  1404.             if (!XMLString::equals(tokenElem,SchemaSymbols::fgATTVAL_TWOPOUNDLOCAL)) { // not ##local
  1405.                 if (XMLString::equals(tokenElem,SchemaSymbols::fgATTVAL_TWOPOUNDTRAGETNAMESPACE)) {
  1406.                     uriIndex = fTargetNSURI;
  1407.                 }
  1408.                 else {
  1409.                     try {
  1410.                         anyURIDV->validate(tokenElem);
  1411.                     }
  1412.                     catch(const XMLException& excep) {
  1413.                         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, excep.getMessage());
  1414.                     }
  1415.                     uriIndex = fURIStringPool->addOrFind(tokenElem);
  1416.                 }
  1417.             }
  1418.             if (uriList.containsElement(uriIndex)) {
  1419.                 continue;
  1420.             }
  1421.             uriList.addElement(uriIndex);
  1422.             firstNode = new (fMemoryManager) ContentSpecNode
  1423.             (
  1424.                 new (fMemoryManager) QName
  1425.                 (
  1426.                     XMLUni::fgZeroLenString
  1427.                     , XMLUni::fgZeroLenString
  1428.                     , uriIndex, fMemoryManager
  1429.                 )
  1430.                 , false
  1431.                 , fMemoryManager
  1432.             );
  1433.             firstNode->setType(anyLocalType);
  1434.             if (secondNode == 0) {
  1435.                 secondNode = firstNode;
  1436.             }
  1437.             else {
  1438.                 secondNode = new (fMemoryManager) ContentSpecNode
  1439.                 (
  1440.                     ContentSpecNode::Choice
  1441.                     , secondNode
  1442.                     , firstNode
  1443.                     , true
  1444.                     , true
  1445.                     , fMemoryManager
  1446.                 );
  1447.             }
  1448.         }
  1449.         retSpecNode = secondNode;
  1450.         delete nameSpaceTokens;
  1451.     }
  1452.     return retSpecNode;
  1453. }
  1454. /**
  1455.   *  Traverse all
  1456.   *
  1457.   *     <all
  1458.   *        id = ID
  1459.   *        maxOccurs = 1 : 1
  1460.   *        minOccurs = (0 | 1) : 1
  1461.   *        {any attributes with non-schema namespace . . .}>
  1462.   *        Content: (annotation?, element*)
  1463.   *     </all>
  1464.   */
  1465. ContentSpecNode*
  1466. TraverseSchema::traverseAll(const DOMElement* const elem) {
  1467.     // ------------------------------------------------------------------
  1468.     // Check attributes
  1469.     // ------------------------------------------------------------------
  1470.     fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::E_All, this);
  1471.     // ------------------------------------------------------------------
  1472.     // Process contents
  1473.     // ------------------------------------------------------------------
  1474.     DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  1475.     if (child == 0) {
  1476.         return 0;
  1477.     }
  1478.     ContentSpecNode* left = 0;
  1479.     ContentSpecNode* right = 0;
  1480.     bool hadContent = false;
  1481.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  1482.         ContentSpecNode* contentSpecNode = 0;
  1483.         const XMLCh* childName = child->getLocalName();
  1484.         if (XMLString::equals(childName, SchemaSymbols::fgELT_ELEMENT)) {
  1485.             QName* eltQName = traverseElementDecl(child);
  1486.             if (eltQName == 0) {
  1487.                 continue;
  1488.             }
  1489.             contentSpecNode = new (fMemoryManager) ContentSpecNode
  1490.             (
  1491.                 eltQName
  1492.                 , false
  1493.                 , fMemoryManager
  1494.             );
  1495.             checkMinMax(contentSpecNode, child, All_Element);
  1496.         }
  1497.         else {
  1498.             reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::AllContentError, childName);
  1499.             continue;
  1500.         }
  1501.         hadContent = true;
  1502.         if (!left) {
  1503.             left = contentSpecNode;
  1504.         }
  1505.         else if (!right) {
  1506.             right = contentSpecNode;
  1507.         }
  1508.         else {
  1509.             left = new (fMemoryManager) ContentSpecNode
  1510.             (
  1511.                 ContentSpecNode::All
  1512.                 , left
  1513.                 , right
  1514.                 , true
  1515.                 , true
  1516.                 , fMemoryManager
  1517.             );
  1518.             right = contentSpecNode;
  1519.         }
  1520.     }
  1521.     if (hadContent) {
  1522.         left = new (fMemoryManager) ContentSpecNode
  1523.         (
  1524.             ContentSpecNode::All
  1525.             , left
  1526.             , right
  1527.             , true
  1528.             , true
  1529.             , fMemoryManager
  1530.         );
  1531.     }
  1532.     return left;
  1533. }
  1534. /**
  1535.   * Traverses Schema attribute declaration.
  1536.   *
  1537.   *       <attribute
  1538.   *         fixed = string
  1539.   *         default = string
  1540.   *         form = qualified | unqualified
  1541.   *         id = ID
  1542.   *         name = NCName
  1543.   *         ref = QName
  1544.   *         type = QName
  1545.   *         use = optional | prohibited | required : optional
  1546.   >
  1547.   *         Content: (annotation? , simpleType?)
  1548.   *       <attribute/>
  1549.   *
  1550.   * @param elem:        the declaration of the attribute under consideration
  1551.   *
  1552.   * @param typeInfo:    Contains the complex type info of the element to which
  1553.   *                     the attribute declaration is attached.
  1554.   *
  1555.   */
  1556. void TraverseSchema::traverseAttributeDecl(const DOMElement* const elem,
  1557.                                            ComplexTypeInfo* const typeInfo,
  1558.                                            const bool topLevel) {
  1559.     const XMLCh*   name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  1560.     const XMLCh*   ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF);
  1561.     bool           nameEmpty = (!name || !*name);
  1562.     bool           refEmpty = (!ref || !*ref);
  1563.     if (nameEmpty && refEmpty) {
  1564.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefAttribute);
  1565.         return;
  1566.     }
  1567.     if (topLevel && nameEmpty) {
  1568.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TopLevelNoNameAttribute);
  1569.         return;
  1570.     }
  1571.     // ------------------------------------------------------------------
  1572.     // Check attributes
  1573.     // ------------------------------------------------------------------
  1574.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_AttributeGlobal
  1575.                                       : (refEmpty) ? GeneralAttributeCheck::E_AttributeLocal
  1576.                                                    : GeneralAttributeCheck::E_AttributeRef;
  1577.     fAttributeCheck.checkAttributes(elem, scope, this, topLevel);
  1578.     const XMLCh* defaultVal = getElementAttValue(elem, SchemaSymbols::fgATT_DEFAULT);
  1579.     const XMLCh* fixedVal = getElementAttValue(elem, SchemaSymbols::fgATT_FIXED);
  1580.     const XMLCh* useVal = getElementAttValue(elem, SchemaSymbols::fgATT_USE);
  1581.     const XMLCh* attForm = getElementAttValue(elem, SchemaSymbols::fgATT_FORM);
  1582.     const XMLCh* dvType = getElementAttValue(elem, SchemaSymbols::fgATT_TYPE);
  1583.     DOMElement* simpleType = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  1584.     bool         badContent = false;
  1585.     while (simpleType != 0) {
  1586.         const XMLCh* contentName = simpleType->getLocalName();
  1587.         if (XMLString::equals(SchemaSymbols::fgELT_SIMPLETYPE, contentName)) {
  1588.             if (XUtil::getNextSiblingElement(simpleType) != 0) {
  1589.                 badContent = true;
  1590.             }
  1591.             break;
  1592.         }
  1593.         badContent = true;
  1594.         simpleType = XUtil::getNextSiblingElement(simpleType);
  1595.     }
  1596.     if (badContent) {
  1597.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidAttributeContent,
  1598.                           (name) ? SchemaSymbols::fgATT_NAME : SchemaSymbols::fgATT_REF,
  1599.                           (name) ? name : ref);
  1600.     }
  1601.     if (defaultVal) {
  1602.         if (fixedVal) {
  1603.             fixedVal = 0;
  1604.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttributeDefaultFixedValue);
  1605.         }
  1606.         if ((useVal && *useVal)
  1607.             && !XMLString::equals(useVal, SchemaSymbols::fgATTVAL_OPTIONAL)) {
  1608.             useVal = 0;
  1609.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NotOptionalDefaultAttValue);
  1610.         }
  1611.     }
  1612.     // processing ref
  1613.     if (!refEmpty && !topLevel) {
  1614.         // Check ref representation OK - 3.2.3::3.2
  1615.         if (attForm || dvType || (simpleType != 0)) {
  1616.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttributeRefContentError);
  1617.         }
  1618.         processAttributeDeclRef(elem, typeInfo, ref, useVal, defaultVal, fixedVal);
  1619.         return;
  1620.     }
  1621.     // processing 'name'
  1622.     if (!XMLString::isValidNCName(name)
  1623.         || XMLString::equals(name, XMLUni::fgXMLNSString)) {
  1624.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, SchemaSymbols::fgELT_ATTRIBUTE, name);
  1625.         return;
  1626.     }
  1627.     // Check for duplicate declaration
  1628.     const XMLCh* qualified = SchemaSymbols::fgATTVAL_QUALIFIED;
  1629.     int uriIndex = fEmptyNamespaceURI;
  1630.     if ((fTargetNSURIString && *fTargetNSURIString)
  1631.         && (topLevel || XMLString::equals(attForm, qualified)
  1632.             || ((fSchemaInfo->getElemAttrDefaultQualified() & Attr_Def_Qualified)
  1633.                 && (!attForm || !*attForm)))) {
  1634.         uriIndex = fTargetNSURI;
  1635.     }
  1636.     // make sure that attribute namespace is not xsi uri
  1637.     if (XMLString::equals(fTargetNSURIString, SchemaSymbols::fgURI_XSI)) {
  1638.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidAttTNS, name);
  1639.         return;
  1640.     }
  1641.     if (typeInfo && typeInfo->getAttDef(name, uriIndex) != 0) {
  1642.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, name);
  1643.         return;
  1644.     }
  1645.     else if (fCurrentAttGroupInfo && fCurrentAttGroupInfo->containsAttribute(name, uriIndex)) {
  1646.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, name);
  1647.         return;
  1648.     }
  1649.     DatatypeValidator*  dv = 0;
  1650.     XMLAttDef::AttTypes attType = XMLAttDef::Simple;
  1651.     SchemaInfo* saveInfo = fSchemaInfo;
  1652.     if (simpleType != 0) {
  1653.         if (dvType && *dvType) {
  1654.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttributeWithTypeAndSimpleType);
  1655.         }
  1656.         dv = traverseSimpleTypeDecl(simpleType, false);
  1657.     }
  1658.     else if (!dvType || !*dvType) {
  1659.         dv = fDatatypeRegistry->getDatatypeValidator(SchemaSymbols::fgDT_ANYSIMPLETYPE);
  1660.     }
  1661.     else {
  1662.         checkEnumerationRequiredNotation(elem, name, dvType);
  1663.         const XMLCh* localPart = getLocalPart(dvType);
  1664.         const XMLCh* prefix = getPrefix(dvType);
  1665.         const XMLCh* typeURI = resolvePrefixToURI(elem, prefix);
  1666.         DatatypeValidator*  dvBack = 0;
  1667.         if (XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
  1668.             dv = fDatatypeRegistry->getDatatypeValidator(localPart);
  1669.             dvBack = dv;
  1670.         }
  1671.         else { //isn't of the schema for schemas namespace...
  1672.             dv = getAttrDatatypeValidatorNS(elem, localPart, typeURI);
  1673.             dvBack = dv;
  1674.             while(dv != 0 && !XMLString::equals(dv->getTypeUri(), SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
  1675.                 dv = dv->getBaseValidator();
  1676.             }
  1677.             if(dv)
  1678.                 localPart = dv->getTypeLocalName();
  1679.         }
  1680.         if(dv) {
  1681.             if (XMLString::equals(localPart,XMLUni::fgIDString)) {
  1682.                 attType = XMLAttDef::ID;
  1683.             }
  1684.             else if (XMLString::equals(localPart,XMLUni::fgIDRefString)) {
  1685.                 attType = XMLAttDef::IDRef;
  1686.             }
  1687.             else if (XMLString::equals(localPart,XMLUni::fgIDRefsString)) {
  1688.                 attType = XMLAttDef::IDRefs;
  1689.             }
  1690.             else if (XMLString::equals(localPart,XMLUni::fgEntityString)) {
  1691.                 attType = XMLAttDef::Entity;
  1692.             }
  1693.             else if (XMLString::equals(localPart,XMLUni::fgEntitiesString)) {
  1694.                 attType = XMLAttDef::Entities;
  1695.             }
  1696.             else if (XMLString::equals(localPart,XMLUni::fgNmTokenString)) {
  1697.                 attType = XMLAttDef::NmToken;
  1698.             }
  1699.             else if (XMLString::equals(localPart,XMLUni::fgNmTokensString)) {
  1700.                 attType = XMLAttDef::NmTokens;
  1701.             }
  1702.             else if (XMLString::equals(localPart,XMLUni::fgNotationString)) {
  1703.                 attType = XMLAttDef::Notation;
  1704.             }
  1705.             else {
  1706.                 attType = XMLAttDef::Simple;
  1707.             }
  1708.         }
  1709.         else 
  1710.             attType = XMLAttDef::Simple;
  1711.         dv = dvBack;
  1712.         if (!dv) {
  1713.             reportSchemaError
  1714.             (
  1715.                 elem
  1716.                 , XMLUni::fgXMLErrDomain
  1717.                 , XMLErrs::AttributeSimpleTypeNotFound
  1718.                 , typeURI
  1719.                 , localPart
  1720.                 , name
  1721.             );
  1722.         }
  1723.     }
  1724.     // restore schema information, if necessary
  1725.     fSchemaInfo = saveInfo;
  1726.     bool required = false;
  1727.     bool prohibited = false;
  1728.     if (useVal && *useVal) {
  1729.         if (XMLString::equals(useVal, SchemaSymbols::fgATTVAL_REQUIRED)) {
  1730.             required = true;
  1731.         }
  1732.         else if (XMLString::equals(useVal, SchemaSymbols::fgATTVAL_PROHIBITED)) {
  1733.             prohibited = true;
  1734.         }
  1735.     }
  1736.     // validate fixed/default values
  1737.     const XMLCh* valueToCheck = defaultVal ? defaultVal : fixedVal;
  1738.     bool  ofTypeID = (dv && dv->getType() == DatatypeValidator::ID);
  1739.     if (attType == XMLAttDef::Simple && dv && valueToCheck) {
  1740.         try {
  1741.             dv->validate(valueToCheck);
  1742.         }
  1743.         catch (const XMLException& excep) {
  1744.             reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  1745.         }
  1746.         catch(...) {
  1747.             reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, valueToCheck);
  1748.         }
  1749.     }
  1750.     if (ofTypeID && valueToCheck) {
  1751.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect3,
  1752.                          SchemaSymbols::fgATT_NAME, name);
  1753.     }
  1754.     // check for multiple attributes with type derived from ID
  1755.     if (!topLevel && ofTypeID) {
  1756.         if (fCurrentAttGroupInfo) {
  1757.             if (fCurrentAttGroupInfo->containsTypeWithId()) {
  1758.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, name);
  1759.                 return;
  1760.             }
  1761.             fCurrentAttGroupInfo->setTypeWithId(true);
  1762.         }
  1763.         else {
  1764.             if (typeInfo->containsAttWithTypeId()) {
  1765.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, name);
  1766.                 return;
  1767.             }
  1768.             typeInfo->setAttWithTypeId(true);
  1769.         }
  1770.     }
  1771.     // create SchemaAttDef
  1772.     SchemaAttDef* attDef = new (fMemoryManager) SchemaAttDef
  1773.     (
  1774.         XMLUni::fgZeroLenString
  1775.         , name
  1776.         , uriIndex
  1777.         , attType
  1778.         , XMLAttDef::Implied
  1779.         , fMemoryManager
  1780.     );
  1781.     attDef->setDatatypeValidator(dv);
  1782.     if (prohibited) {
  1783.         attDef->setDefaultType(XMLAttDef::Prohibited);
  1784.     }
  1785.     else if (required) {
  1786.         if (fixedVal) {
  1787.             attDef->setDefaultType(XMLAttDef::Required_And_Fixed);
  1788.         }
  1789.         else {
  1790.             attDef->setDefaultType(XMLAttDef::Required);
  1791.         }
  1792.     }
  1793.     else {
  1794.         if (fixedVal) {
  1795.             attDef->setDefaultType(XMLAttDef::Fixed);
  1796.         }
  1797.         else if (defaultVal) {
  1798.             attDef->setDefaultType(XMLAttDef::Default);
  1799.         }
  1800.     }
  1801.     if (valueToCheck) {
  1802.         attDef->setValue(valueToCheck);
  1803.     }
  1804.     if (topLevel) {
  1805.         fAttributeDeclRegistry->put((void*) fStringPool->getValueForId(fStringPool->addOrFind(name)), attDef);
  1806.     }
  1807.     else {
  1808.         bool toClone = false;
  1809.         if (typeInfo) {
  1810.             toClone = true;
  1811.             typeInfo->addAttDef(attDef);
  1812.         }
  1813.         if (fCurrentAttGroupInfo) {
  1814.             fCurrentAttGroupInfo->addAttDef(attDef, toClone);
  1815.         }
  1816.     }
  1817. }
  1818. /**
  1819.   * Traverses Schema element declaration.
  1820.   *
  1821.   *       <element
  1822.   *            abstract = boolean : false
  1823.   *            block = (#all | List of (substitution | extension | restriction
  1824.   *                                     | list | union))
  1825.   *            default = string
  1826.   *            final = (#all | List of (extension | restriction))
  1827.   *            fixed = string
  1828.   *            form = (qualified | unqualified)
  1829.   *            id = ID
  1830.   *            maxOccurs = (nonNegativeInteger | unbounded)  : 1
  1831.   *            minOccurs = nonNegativeInteger : 1
  1832.   *            name = NCName
  1833.   *            nillable = boolean : false
  1834.   *            ref = QName
  1835.   *            substitutionGroup = QName
  1836.   *            type = QName
  1837.   *            Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
  1838.   *       </element>
  1839.   *
  1840.   * @param elem:  the declaration of the element under consideration
  1841.   */
  1842. QName* TraverseSchema::traverseElementDecl(const DOMElement* const elem,
  1843.                                            const bool topLevel) {
  1844.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  1845.     const XMLCh* ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF);
  1846.     bool         nameEmpty = (!name || !*name) ? true : false;
  1847.     bool         refEmpty = (!ref || !*ref) ? true : false;
  1848.     if (nameEmpty && topLevel) {
  1849.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::GlobalNoNameElement);
  1850.         return 0;
  1851.     }
  1852.     if (nameEmpty && refEmpty) {
  1853.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefElement);
  1854.         return 0;
  1855.     }
  1856.     if (topLevel) {
  1857.         if (fSchemaGrammar->getElemDecl(fTargetNSURI, name, 0, Grammar::TOP_LEVEL_SCOPE) != 0) {
  1858.             return new (fMemoryManager) QName(name, fTargetNSURI, fMemoryManager);
  1859.         }
  1860.     }
  1861.     // ------------------------------------------------------------------
  1862.     // Check attributes
  1863.     // ------------------------------------------------------------------
  1864.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_ElementGlobal
  1865.                               : (refEmpty) ? GeneralAttributeCheck::E_ElementLocal
  1866.                                                    : GeneralAttributeCheck::E_ElementRef;
  1867.     fAttributeCheck.checkAttributes(elem, scope, this, topLevel);
  1868.     // ------------------------------------------------------------------
  1869.     // Process contents
  1870.     // ------------------------------------------------------------------
  1871.     const XMLCh* fixed = getElementAttValue(elem, SchemaSymbols::fgATT_FIXED);
  1872.     const XMLCh* deflt = getElementAttValue(elem, SchemaSymbols::fgATT_DEFAULT);
  1873.     if((fixed && *fixed) && (deflt && *deflt)) {
  1874.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ElementWithFixedAndDefault);
  1875.     }
  1876.     if (nameEmpty || (!refEmpty && !topLevel)) {
  1877.         if (!nameEmpty) {
  1878.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationWithNameRef,
  1879.                               SchemaSymbols::fgELT_ELEMENT, name);
  1880.         }
  1881.         if (!isValidRefDeclaration(elem)) {
  1882.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttWithRef);
  1883.         }
  1884.         return processElementDeclRef(elem, ref);
  1885.     }
  1886.     // Name is notEmpty
  1887.     if (!XMLString::isValidNCName(name)) {
  1888.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  1889.                           SchemaSymbols::fgELT_ELEMENT, name);
  1890.         return 0;
  1891.     }
  1892.     const XMLCh*                  anotherSchemaURI = 0;
  1893.     int                           scopeDefined = Grammar::UNKNOWN_SCOPE;
  1894.     bool                          noErrorFound = true;
  1895.     bool                          anonymousType = false;
  1896.     DatatypeValidator*            validator = 0;
  1897.     DatatypeValidator*            subGroupValidator = 0;
  1898.     ComplexTypeInfo*              typeInfo = 0;
  1899.     ComplexTypeInfo*              subGroupTypeInfo = 0;
  1900.     ContentSpecNode*              contentSpecNode = 0;
  1901.     SchemaElementDecl::ModelTypes contentSpecType = SchemaElementDecl::Any;
  1902.     // Create element decl
  1903.     bool isDuplicate = false;
  1904.     SchemaElementDecl* elemDecl =
  1905.        createSchemaElementDecl(elem, topLevel, contentSpecType, isDuplicate, (fixed != 0));
  1906.     if (elemDecl == 0) {
  1907.         return 0;
  1908.     }
  1909.     if (!isDuplicate) {
  1910.         fSchemaGrammar->putElemDecl(elemDecl);
  1911.         if (fCurrentGroupInfo &&
  1912.             elemDecl->getEnclosingScope() == fCurrentGroupInfo->getScope()) {
  1913.             fCurrentGroupInfo->addElement(elemDecl);
  1914.         }
  1915.         if (fCurrentComplexType &&
  1916.             elemDecl->getEnclosingScope() == fCurrentComplexType->getScopeDefined()) {
  1917.             fCurrentComplexType->addElement(elemDecl);
  1918.         }
  1919.     }
  1920.     // Resolve the type for the element
  1921.     const DOMElement*  content = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  1922.     if (content != 0) {
  1923.         const XMLCh* contentName = content->getLocalName();
  1924.         if (XMLString::equals(contentName, SchemaSymbols::fgELT_COMPLEXTYPE)) {
  1925.             const XMLCh* temp = content->getAttribute(SchemaSymbols::fgATT_NAME);
  1926.             if (temp && *temp) {
  1927.                 // REVISIT - we are bypassing the complex type declaration.
  1928.                 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AnonComplexTypeWithName, name);
  1929.             }
  1930.             else {
  1931.                 typeInfo = checkForComplexTypeInfo(content);
  1932.             }
  1933.             if (!typeInfo) {
  1934.                 noErrorFound = false;
  1935.             }
  1936.             else if (!isDuplicate) {
  1937.                 typeInfo->setElementId(elemDecl->getId());
  1938.                 //Recursing element
  1939.                 if (typeInfo->getPreprocessed()) {
  1940.                     const XMLCh* typeInfoName = typeInfo->getTypeName();
  1941.                     fSchemaInfo->addRecursingType(content, typeInfoName + XMLString::indexOf(typeInfoName, chComma) + 1);
  1942.                 }
  1943.             }
  1944.             anonymousType = true;
  1945.             content = XUtil::getNextSiblingElement(content);
  1946.         }
  1947.         else if (XMLString::equals(contentName, SchemaSymbols::fgELT_SIMPLETYPE)) {
  1948.             const XMLCh* temp = content->getAttribute(SchemaSymbols::fgATT_NAME);
  1949.             if (temp && *temp) {
  1950.                 // REVISIT - we are bypassing the simple type declaration.
  1951.                 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AnonSimpleTypeWithName, name);
  1952.             }
  1953.             else {
  1954.                 validator = checkForSimpleTypeValidator(content);
  1955.             }
  1956.             if (!validator) {
  1957.                 noErrorFound = false;
  1958.             }
  1959.             contentSpecType = SchemaElementDecl::Simple;
  1960.             anonymousType = true;
  1961.             content = XUtil::getNextSiblingElement(content);
  1962.         }
  1963.         // Check for identity constraints
  1964.         if (content != 0) {
  1965.             content = checkIdentityConstraintContent(content);
  1966.             if (content != 0) {
  1967.                 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::InvalidElementContent);
  1968.             }
  1969.         }
  1970.     }
  1971.     // Handle 'type' attribute
  1972.     const XMLCh* typeStr = getElementAttValue(elem, SchemaSymbols::fgATT_TYPE);
  1973.     if (typeStr && *typeStr) {
  1974.         if (anonymousType) {
  1975.             noErrorFound = false;
  1976.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ElementWithTypeAndAnonType, name);
  1977.         }
  1978.         else {
  1979.             const XMLCh* typeLocalPart = getLocalPart(typeStr);
  1980.             const XMLCh* typePrefix = getPrefix(typeStr);
  1981.             const XMLCh* typeURI = resolvePrefixToURI(elem, typePrefix);
  1982.             if (!XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)
  1983.                 || !XMLString::equals(typeLocalPart, SchemaSymbols::fgATTVAL_ANYTYPE)) {
  1984.                 checkEnumerationRequiredNotation(elem, name, typeStr);
  1985.                 anotherSchemaURI = checkTypeFromAnotherSchema(elem, typeStr);
  1986.                 // get complex type info
  1987.                 typeInfo = getElementComplexTypeInfo(elem, typeStr, noErrorFound, anotherSchemaURI);
  1988.                 // get simple type validtor - if not a complex type