Esempio n. 1
0
// -----------------------------------------------------------------------
//  Virtual methods
// -----------------------------------------------------------------------
XMLElementDecl* SchemaGrammar::findOrAddElemDecl (const   unsigned int    uriId
        , const XMLCh* const    baseName
        , const XMLCh* const    prefixName
        , const XMLCh* const    qName
        , unsigned int          scope
        ,       bool&           wasAdded )
{
    // See it it exists
    SchemaElementDecl* retVal = (SchemaElementDecl*) getElemDecl(uriId, baseName, qName, scope);

    // if not, then add this in
    if (!retVal)
    {
        retVal = new (fMemoryManager) SchemaElementDecl
        (
            prefixName
            , baseName
            , uriId
            , SchemaElementDecl::Any
            , Grammar::TOP_LEVEL_SCOPE
            , fMemoryManager
        );
        if(!fElemNonDeclPool)
            fElemNonDeclPool = new (fMemoryManager) RefHash3KeysIdPool<SchemaElementDecl>(29, true, 128, fMemoryManager);
        const unsigned int elemId = fElemNonDeclPool->put((void*)retVal->getBaseName(), uriId, scope, retVal);
        retVal->setId(elemId);
        wasAdded = true;
    }
     else
    {
        wasAdded = false;
    }
    return retVal;
}
Esempio n. 2
0
XMLElementDecl* SchemaGrammar::putElemDecl (const   unsigned int    uriId
        , const XMLCh* const    baseName
        , const XMLCh* const    prefixName
        , const XMLCh* const
        , unsigned int          scope
        , const bool            notDeclared)
{
    SchemaElementDecl* retVal = new (fMemoryManager) SchemaElementDecl
    (
        prefixName
        , baseName
        , uriId
        , SchemaElementDecl::Any
        , Grammar::TOP_LEVEL_SCOPE
        , fMemoryManager
    );
    if(notDeclared)
    {
        if(!fElemNonDeclPool)
            fElemNonDeclPool = new (fMemoryManager) RefHash3KeysIdPool<SchemaElementDecl>(29, true, 128, fMemoryManager);
        retVal->setId(fElemNonDeclPool->put((void*)retVal->getBaseName(), uriId, scope, retVal));
    } else 
    {
        retVal->setId(fElemDeclPool->put((void*)retVal->getBaseName(), uriId, scope, retVal));
    }
    return retVal;
}
Esempio n. 3
0
XSModelGroupDefinition*
XSObjectFactory::createXSModelGroupDefinition(XercesGroupInfo* const groupInfo,
                                              XSModel* const xsModel)
{
    XSParticle* particle = createModelGroupParticle(
            groupInfo->getContentSpec(), xsModel);

    XSModelGroupDefinition* xsObj = new (fMemoryManager) XSModelGroupDefinition
    (
        groupInfo
        , particle
        , getAnnotationFromModel(xsModel, groupInfo)
        , xsModel
        , fMemoryManager
    );
    fDeleteVector->addElement(xsObj);

    // process local elements
    XMLSize_t elemCount = groupInfo->elementCount();
    for (XMLSize_t j=0; j<elemCount; j++)
    {
        SchemaElementDecl* elemDecl = groupInfo->elementAt(j);

        if (elemDecl->getEnclosingScope() == groupInfo->getScope())
            addOrFind(elemDecl, xsModel);
    }

    return xsObj;
}
Esempio n. 4
0
bool XSAXMLScanner::scanStartTag(bool& gotData)
{
    //  Assume we will still have data until proven otherwise. It will only
    //  ever be false if this is the root and its empty.
    gotData = true;

    // Reset element content
    fContent.reset();

    //  The current position is after the open bracket, so we need to read in
    //  in the element name.
    int prefixColonPos;
    if (!fReaderMgr.getQName(fQNameBuf, &prefixColonPos))
    {       
        if (fQNameBuf.isEmpty())
            emitError(XMLErrs::ExpectedElementName);
        else
            emitError(XMLErrs::InvalidElementName, fQNameBuf.getRawBuffer());
        fReaderMgr.skipToChar(chOpenAngle);
        return false;
    }

    // See if its the root element
    const bool isRoot = fElemStack.isEmpty();

    // Skip any whitespace after the name
    fReaderMgr.skipPastSpaces();

    //  First we have to do the rawest attribute scan. We don't do any
    //  normalization of them at all, since we don't know yet what type they
    //  might be (since we need the element decl in order to do that.)
    const XMLCh* qnameRawBuf = fQNameBuf.getRawBuffer();
    bool isEmpty;
    unsigned int attCount = rawAttrScan(qnameRawBuf, *fRawAttrList, isEmpty);

    // save the contentleafname and currentscope before addlevel, for later use
    ContentLeafNameTypeVector* cv = 0;
    XMLContentModel* cm = 0;
    int currentScope = Grammar::TOP_LEVEL_SCOPE;
    bool laxThisOne = false;
    if (!isRoot)
    {
        // schema validator will have correct type if validating
        SchemaElementDecl* tempElement = (SchemaElementDecl*)
            fElemStack.topElement()->fThisElement;
        SchemaElementDecl::ModelTypes modelType = tempElement->getModelType();
        ComplexTypeInfo *currType = 0;

        if (fValidate)
        {
            currType = ((SchemaValidator*)fValidator)->getCurrentTypeInfo();
            if (currType)
                modelType = (SchemaElementDecl::ModelTypes)currType->getContentType();
            else // something must have gone wrong
                modelType = SchemaElementDecl::Any;
        }
        else {
            currType = tempElement->getComplexTypeInfo();
        }

        if ((modelType == SchemaElementDecl::Mixed_Simple)
          ||  (modelType == SchemaElementDecl::Mixed_Complex)
          ||  (modelType == SchemaElementDecl::Children))
        {
            cm = currType->getContentModel();
            cv = cm->getContentLeafNameTypeVector();
            currentScope = fElemStack.getCurrentScope();
        }
        else if (modelType == SchemaElementDecl::Any) {
            laxThisOne = true;
        }
    }

    //  Now, since we might have to update the namespace map for this element,
    //  but we don't have the element decl yet, we just tell the element stack
    //  to expand up to get ready.
    unsigned int elemDepth = fElemStack.addLevel();
    fElemStack.setValidationFlag(fValidate);
    fElemStack.setPrefixColonPos(prefixColonPos);

    //  Make an initial pass through the list and find any xmlns attributes or
    //  schema attributes.
    if (attCount)
        scanRawAttrListforNameSpaces(attCount);

    //  Resolve the qualified name to a URI and name so that we can look up
    //  the element decl for this element. We have now update the prefix to
    //  namespace map so we should get the correct element now.    
    unsigned int uriId = resolveQNameWithColon
    (
        qnameRawBuf, fPrefixBuf, ElemStack::Mode_Element, prefixColonPos
    );

    //if schema, check if we should lax or skip the validation of this element
    bool parentValidation = fValidate;
    if (cv) {
        QName element(fPrefixBuf.getRawBuffer(), &qnameRawBuf[prefixColonPos + 1], uriId, fMemoryManager);
        // elementDepth will be > 0, as cv is only constructed if element is not
        // root.
        laxThisOne = laxElementValidation(&element, cv, cm, elemDepth - 1);
    }

    //  Look up the element now in the grammar. This will get us back a
    //  generic element decl object. We tell him to fault one in if he does
    //  not find it.
    bool wasAdded = false;
    const XMLCh* nameRawBuf = &qnameRawBuf[prefixColonPos + 1];
    XMLElementDecl* elemDecl = fGrammar->getElemDecl
    (
        uriId, nameRawBuf, qnameRawBuf, currentScope
    );

    if (!elemDecl)
    {
        // URI is different, so we try to switch grammar
        if (uriId != fURIStringPool->getId(fGrammar->getTargetNamespace())) {
            switchGrammar(getURIText(uriId), laxThisOne);
        }

        // look for a global element declaration
        elemDecl = fGrammar->getElemDecl(
            uriId, nameRawBuf, qnameRawBuf, Grammar::TOP_LEVEL_SCOPE
        );

        if (!elemDecl)
        {
            // if still not found, look in list of undeclared elements
            elemDecl = fElemNonDeclPool->getByKey(
                nameRawBuf, uriId, Grammar::TOP_LEVEL_SCOPE);

            if (!elemDecl)
            {
                elemDecl = new (fMemoryManager) SchemaElementDecl
                (
                    fPrefixBuf.getRawBuffer(), nameRawBuf, uriId
                    , SchemaElementDecl::Any, Grammar::TOP_LEVEL_SCOPE
                    , fMemoryManager
                );
                elemDecl->setId
                (
                    fElemNonDeclPool->put
                    (
                        (void*)elemDecl->getBaseName(), uriId
                        , Grammar::TOP_LEVEL_SCOPE, (SchemaElementDecl*)elemDecl
                    )
                );
                wasAdded = true;
            }
		}
    }

    //  We do something different here according to whether we found the
    //  element or not.
    if (wasAdded || !elemDecl->isDeclared())
    {
        if (laxThisOne) {
            fValidate = false;
            fElemStack.setValidationFlag(fValidate);
        }

        // If validating then emit an error
        if (fValidate)
        {
            // This is to tell the reuse Validator that this element was
            // faulted-in, was not an element in the grammar pool originally
            elemDecl->setCreateReason(XMLElementDecl::JustFaultIn);

            fValidator->emitError
            (
                XMLValid::ElementNotDefined, elemDecl->getFullName()
            );
        }
    }

    //  Now we can update the element stack to set the current element
    //  decl. We expanded the stack above, but couldn't store the element
    //  decl because we didn't know it yet.
    fElemStack.setElement(elemDecl, fReaderMgr.getCurrentReaderNum());
    fElemStack.setCurrentURI(uriId);

    if (isRoot) {
        fRootElemName = XMLString::replicate(qnameRawBuf, fMemoryManager);
    }

    //  Validate the element
    if (fValidate) {
        fValidator->validateElement(elemDecl);
    }

    // squirrel away the element's QName, so that we can do an efficient
    // end-tag match
    fElemStack.setCurrentSchemaElemName(fQNameBuf.getRawBuffer());

    ComplexTypeInfo* typeinfo = (fValidate)
        ? ((SchemaValidator*)fValidator)->getCurrentTypeInfo()
        : ((SchemaElementDecl*) elemDecl)->getComplexTypeInfo();

    if (typeinfo)
    {
        currentScope = typeinfo->getScopeDefined();

        // switch grammar if the typeinfo has a different grammar
        XMLCh* typeName = typeinfo->getTypeName();
        int comma = XMLString::indexOf(typeName, chComma);
        if (comma > 0)
        {
            XMLBufBid bbPrefix(&fBufMgr);
            XMLBuffer& prefixBuf = bbPrefix.getBuffer();

            prefixBuf.append(typeName, comma);
            switchGrammar(prefixBuf.getRawBuffer(), laxThisOne);
        }
    }
    fElemStack.setCurrentScope(currentScope);

    // Set element next state
    if (elemDepth >= fElemStateSize) {
        resizeElemState();
    }

    fElemState[elemDepth] = 0;
    fElemStack.setCurrentGrammar(fGrammar);

    //  If this is the first element and we are validating, check the root
    //  element.
    if (!isRoot && parentValidation) {
        fElemStack.addChild(elemDecl->getElementName(), true);
    }

    //  Now lets get the fAttrList filled in. This involves faulting in any
    //  defaulted and fixed attributes and normalizing the values of any that
    //  we got explicitly.
    //
    //  We update the attCount value with the total number of attributes, but
    //  it goes in with the number of values we got during the raw scan of
    //  explictly provided attrs above.
    attCount = buildAttList(*fRawAttrList, attCount, elemDecl, *fAttrList);

    if(attCount)
    {
        // clean up after ourselves:
        // clear the map used to detect duplicate attributes
        fUndeclaredAttrRegistryNS->removeAll();
    }

    // Since the element may have default values, call start tag now regardless if it is empty or not
    // If we have a document handler, then tell it about this start tag
    if (fDocHandler)
    {
        fDocHandler->startElement
        (
            *elemDecl, uriId, fPrefixBuf.getRawBuffer(), *fAttrList
            , attCount, false, isRoot
        );
    } // may be where we output something...

    //  If empty, validate content right now if we are validating and then
    //  pop the element stack top. Else, we have to update the current stack
    //  top's namespace mapping elements.
    if (isEmpty)
    {
        // Pop the element stack back off since it'll never be used now
        fElemStack.popTop();

        // If validating, then insure that its legal to have no content
        if (fValidate)
        {
            const int res = fValidator->checkContent(elemDecl, 0, 0);
            if (res >= 0)
            {
                // REVISIT:  in the case of xsi:type, this may
                // return the wrong string...
                fValidator->emitError
                (
                    XMLValid::ElementNotValidForContent
                    , elemDecl->getFullName()
                    , elemDecl->getFormattedContentModel()
                );
            }
        }

        // If we have a doc handler, tell it about the end tag
        if (fDocHandler)
        {
            fDocHandler->endElement
            (
                *elemDecl, uriId, isRoot, fPrefixBuf.getRawBuffer()
            );
        }

        // If the elem stack is empty, then it was an empty root
        if (isRoot) {
            gotData = false;
        }
        else
        {
            // Restore the grammar
            fGrammar = fElemStack.getCurrentGrammar();
            fGrammarType = fGrammar->getGrammarType();
            fValidator->setGrammar(fGrammar);

            // Restore the validation flag
            fValidate = fElemStack.getValidationFlag();
        }
    }

    return true;
}
Esempio n. 5
0
void process(char* const xmlFile)
{
    //
    //  Create a Schema validator to be used for our validation work. Then create
    //  a SAX parser object and pass it our validator. Then, according to what
    //  we were told on the command line, set it to validate or not. He owns
    //  the validator, so we have to allocate it.
    //
    SAXParser parser;
    parser.setValidationScheme(SAXParser::Val_Always);
    parser.setDoNamespaces(true);
    parser.setDoSchema(true);

	parser.parse(xmlFile);

    if (parser.getErrorCount())
	{
        XERCES_STD_QUALIFIER cout << "\nErrors occurred, no output available\n" << XERCES_STD_QUALIFIER endl;
		return;
	}

	if (!parser.getValidator().handlesSchema())
	{
		XERCES_STD_QUALIFIER cout << "\n Non schema document, no output available\n" << XERCES_STD_QUALIFIER endl;
		return;
	}

	Grammar* rootGrammar = parser.getRootGrammar();
	if (!rootGrammar || rootGrammar->getGrammarType() != Grammar::SchemaGrammarType)
	{
		XERCES_STD_QUALIFIER cout << "\n Non schema grammar, no output available\n" << XERCES_STD_QUALIFIER endl;
		return;
	}

	//
	//  Now we will get an enumerator for the element pool from the validator
	//  and enumerate the elements, printing them as we go. For each element
	//  we get an enumerator for its attributes and print them also.
	//

	SchemaGrammar* grammar = (SchemaGrammar*) rootGrammar;
	RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = grammar->getElemEnumerator();

	if (!elemEnum.hasMoreElements())
	{
		XERCES_STD_QUALIFIER cout << "\nThe validator has no elements to display\n" << XERCES_STD_QUALIFIER endl;
		return;
	}

	while(elemEnum.hasMoreElements())
	{
		const SchemaElementDecl& curElem = elemEnum.nextElement();

		// Name
		XERCES_STD_QUALIFIER cout << "Name:\t\t\t" << StrX(curElem.getFullName()) << "\n";

		// Model Type
		XERCES_STD_QUALIFIER cout << "Model Type:\t\t";
		switch( curElem.getModelType() )
		{
		case SchemaElementDecl::Empty:          XERCES_STD_QUALIFIER cout << "Empty";         break;
		case SchemaElementDecl::Any:            XERCES_STD_QUALIFIER cout << "Any";           break;
		case SchemaElementDecl::Mixed_Simple:   XERCES_STD_QUALIFIER cout << "Mixed_Simple";  break;
		case SchemaElementDecl::Mixed_Complex:  XERCES_STD_QUALIFIER cout << "Mixed_Complex"; break;
		case SchemaElementDecl::Children:       XERCES_STD_QUALIFIER cout << "Children";      break;
		case SchemaElementDecl::Simple:         XERCES_STD_QUALIFIER cout << "Simple";        break;
        case SchemaElementDecl::ElementOnlyEmpty:    XERCES_STD_QUALIFIER cout << "ElementOnlyEmpty";    break;

		default:                                XERCES_STD_QUALIFIER cout << "Unknown";       break;
		}

		XERCES_STD_QUALIFIER cout << "\n";

		// Create Reason
		XERCES_STD_QUALIFIER cout << "Create Reason:\t";
		switch( curElem.getCreateReason() )
		{
		case XMLElementDecl::NoReason:          XERCES_STD_QUALIFIER cout << "Empty";            break;
		case XMLElementDecl::Declared:          XERCES_STD_QUALIFIER cout << "Declared";         break;
		case XMLElementDecl::AttList:           XERCES_STD_QUALIFIER cout << "AttList";          break;
		case XMLElementDecl::InContentModel:    XERCES_STD_QUALIFIER cout << "InContentModel";   break;
		case XMLElementDecl::AsRootElem:        XERCES_STD_QUALIFIER cout << "AsRootElem";       break;
		case XMLElementDecl::JustFaultIn:       XERCES_STD_QUALIFIER cout << "JustFaultIn";      break;

		default:                            XERCES_STD_QUALIFIER cout << "Unknown";  break;
		}

		XERCES_STD_QUALIFIER cout << "\n";

		// Content Spec Node
		processContentSpecNode( curElem.getContentSpec() );

		// Misc Flags
		int mflags = curElem.getMiscFlags();
		if( mflags !=0 )
		{
			XERCES_STD_QUALIFIER cout << "Misc. Flags:\t";
		}

        if ( mflags & SchemaSymbols::XSD_NILLABLE )
			XERCES_STD_QUALIFIER cout << "Nillable ";

		if ( mflags & SchemaSymbols::XSD_ABSTRACT )
			XERCES_STD_QUALIFIER cout << "Abstract ";

		if ( mflags & SchemaSymbols::XSD_FIXED )
			XERCES_STD_QUALIFIER cout << "Fixed ";

		if( mflags !=0 )
		{
			XERCES_STD_QUALIFIER cout << "\n";
		}

		// Substitution Name
		SchemaElementDecl* subsGroup = curElem.getSubstitutionGroupElem();
		if( subsGroup )
		{
			const XMLCh* uriText = parser.getURIText(subsGroup->getURI());
			XERCES_STD_QUALIFIER cout << "Substitution Name:\t" << StrX(uriText)
			     << "," << StrX(subsGroup->getBaseName()) << "\n";
		}

		// Content Model
		const XMLCh* fmtCntModel = curElem.getFormattedContentModel();
		if( fmtCntModel != NULL )
		{
			XERCES_STD_QUALIFIER cout << "Content Model:\t" << StrX(fmtCntModel) << "\n";
		}

		const ComplexTypeInfo* ctype = curElem.getComplexTypeInfo();
		if( ctype != NULL)
		{
			XERCES_STD_QUALIFIER cout << "ComplexType:\n";
			XERCES_STD_QUALIFIER cout << "\tTypeName:\t" << StrX(ctype->getTypeName()) << "\n";

			ContentSpecNode* cSpecNode = ctype->getContentSpec();
			processContentSpecNode(cSpecNode, true );
		}

		// Datatype
		DatatypeValidator* dtValidator = curElem.getDatatypeValidator();
		processDatatypeValidator( dtValidator );

		// Get an enumerator for this guy's attributes if any
		if ( curElem.hasAttDefs() )
		{
			processAttributes( curElem.getAttDefList() );
		}

		XERCES_STD_QUALIFIER cout << "--------------------------------------------";
		XERCES_STD_QUALIFIER cout << XERCES_STD_QUALIFIER endl;

    }

    return;
}
Esempio n. 6
0
XSComplexTypeDefinition*
XSObjectFactory::addOrFind(ComplexTypeInfo* const typeInfo,
                           XSModel* const xsModel)
{
    XSComplexTypeDefinition* xsObj = (XSComplexTypeDefinition*) xsModel->getXSObject(typeInfo);
    if (!xsObj)
    {
        XSWildcard*             xsWildcard = 0;
        XSSimpleTypeDefinition* xsSimpleType = 0;
        XSAttributeUseList*     xsAttList = 0;
        XSTypeDefinition*       xsBaseType = 0;
        XSParticle*             xsParticle = 0;

        if (typeInfo->getAttWildCard())
            xsWildcard = createXSWildcard(typeInfo->getAttWildCard(), xsModel);

        if ((typeInfo->getContentType() == SchemaElementDecl::Simple) &&
            (typeInfo->getDatatypeValidator()))
            xsSimpleType = addOrFind(typeInfo->getDatatypeValidator(), xsModel);

        XMLSize_t attCount=0;
        if (typeInfo->hasAttDefs())
        {
            SchemaAttDefList& attDefList = (SchemaAttDefList&) typeInfo->getAttDefList();
            attCount = attDefList.getAttDefCount();
            xsAttList = new (fMemoryManager) RefVectorOf<XSAttributeUse>(attCount, false, fMemoryManager);
            // create list now put fill it in after we put complextype into map
            // otherwise we may encounter an infinite loop: complextype needs to
            // addorfind attdef, which does an addorfind on the enclosingCTdefintion.
        }

        // compute fBase
        bool isAnyType = false;
        if (typeInfo->getBaseComplexTypeInfo() == typeInfo) // case of anyType
            isAnyType = true;
        else if (typeInfo->getBaseComplexTypeInfo())
            xsBaseType = addOrFind(typeInfo->getBaseComplexTypeInfo(), xsModel);
        else if (typeInfo->getBaseDatatypeValidator())
            xsBaseType = addOrFind(typeInfo->getBaseDatatypeValidator(), xsModel);
        else // base is anyType
            xsBaseType = xsModel->getTypeDefinition(SchemaSymbols::fgATTVAL_ANYTYPE, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);

        // compute particle
        ContentSpecNode* contentSpec = typeInfo->getContentSpec();
        if (contentSpec)
            xsParticle = createModelGroupParticle(contentSpec, xsModel);

        xsObj = new (fMemoryManager) XSComplexTypeDefinition
        (
            typeInfo
            , xsWildcard
            , xsSimpleType
            , xsAttList
            , xsBaseType
            , xsParticle
            , getAnnotationFromModel(xsModel, typeInfo)
            , xsModel
            , fMemoryManager
        );
        putObjectInMap(typeInfo, xsObj);

        if (isAnyType)
            xsObj->setBaseType(xsObj);

        if (typeInfo->hasAttDefs())
        {
            // now create the xsattributedeclarations...
            SchemaAttDefList& attDefList = (SchemaAttDefList&) typeInfo->getAttDefList();
            for(unsigned int i=0; i<attCount; i++)
            {
                XSAttributeDeclaration* xsAttDecl = 0;
                SchemaAttDef& attDef = (SchemaAttDef&) attDefList.getAttDef(i);

                if (attDef.getBaseAttDecl())
                {
                    xsAttDecl = addOrFind(attDef.getBaseAttDecl(), xsModel);
                    fXercesToXSMap->put(&attDef, xsAttDecl);
                }
                else
                    xsAttDecl = addOrFind(&attDef, xsModel, xsObj);

                if (attDef.getDefaultType() != XMLAttDef::Prohibited) {

                    XSAttributeUse* attUse = createXSAttributeUse(xsAttDecl, xsModel);
                    xsAttList->addElement(attUse);
                    processAttUse(&attDef, attUse);
                }
            }
        }

        // process local elements
        XMLSize_t elemCount = typeInfo->elementCount();
        for (XMLSize_t j=0; j<elemCount; j++)
        {
            SchemaElementDecl* elemDecl = typeInfo->elementAt(j);

            if (elemDecl->getEnclosingScope() == typeInfo->getScopeDefined()
                && elemDecl->getPSVIScope() == PSVIDefs::SCP_LOCAL)
                addOrFind(elemDecl, xsModel, xsObj);
        }
    }

    return xsObj;
}
XERCES_CPP_NAMESPACE_BEGIN

bool SubstitutionGroupComparator::isEquivalentTo(QName* const anElement
                                               , QName* const exemplar)
{
    if (!anElement && !exemplar)
        return true;

    if ((!anElement && exemplar) || (anElement && !exemplar))
        return false;


    if (XMLString::equals(anElement->getLocalPart(), exemplar->getLocalPart()) &&
        (anElement->getURI() == exemplar->getURI()))
        return true; // they're the same!

    if (!fGrammarResolver || !fStringPool )
    {
        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::SubGrpComparator_NGR, anElement->getMemoryManager());
    }

    unsigned int uriId = anElement->getURI();
    if (uriId == XMLContentModel::gEOCFakeId ||
        uriId == XMLContentModel::gEpsilonFakeId ||
        uriId == XMLElementDecl::fgPCDataElemId ||
        uriId == XMLElementDecl::fgInvalidElemId)
        return false;

    const XMLCh* uri = fStringPool->getValueForId(uriId);
    const XMLCh* localpart = anElement->getLocalPart();

    // In addition to simply trying to find a chain between anElement and exemplar,
    // we need to make sure that no steps in the chain are blocked.
    // That is, at every step, we need to make sure that the element
    // being substituted for will permit being substituted
    // for, and whether the type of the element will permit derivations in
    // instance documents of this sort.

    if (!uri)
        return false;

    SchemaGrammar *sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(uri);
    if (!sGrammar || sGrammar->getGrammarType() == Grammar::DTDGrammarType)
        return false;

    SchemaElementDecl* anElementDecl = (SchemaElementDecl*) sGrammar->getElemDecl(uriId, localpart, 0, Grammar::TOP_LEVEL_SCOPE);
    if (!anElementDecl)
        return false;

    SchemaElementDecl* pElemDecl = anElementDecl->getSubstitutionGroupElem();
    bool foundIt = false;

    while (pElemDecl) //(substitutionGroupFullName)
    {
        if (XMLString::equals(pElemDecl->getBaseName(), exemplar->getLocalPart()) &&
            (pElemDecl->getURI() == exemplar->getURI()))
        {
            // time to check for block value on element
            if((pElemDecl->getBlockSet() & SchemaSymbols::XSD_SUBSTITUTION) != 0)
                return false;

            foundIt = true;
            break;
        }

        pElemDecl = pElemDecl->getSubstitutionGroupElem();
    }//while

    if (!foundIt)
        return false;

    // this will contain anElement's complexType information.
    ComplexTypeInfo *aComplexType = anElementDecl->getComplexTypeInfo();
    int exemplarBlockSet = pElemDecl->getBlockSet();

    if(!aComplexType)
    {
        // check on simpleType case
        DatatypeValidator *anElementDV = anElementDecl->getDatatypeValidator();
        DatatypeValidator *exemplarDV = pElemDecl->getDatatypeValidator();

        return((anElementDV == 0) ||
            ((anElementDV == exemplarDV) ||
            ((exemplarBlockSet & SchemaSymbols::XSD_RESTRICTION) == 0)));
    }

    // now we have to make sure there are no blocks on the complexTypes that this is based upon
    int anElementDerivationMethod = aComplexType->getDerivedBy();
    if((anElementDerivationMethod & exemplarBlockSet) != 0)
        return false;

    // this will contain exemplar's complexType information.
    ComplexTypeInfo *exemplarComplexType = pElemDecl->getComplexTypeInfo();

    for(ComplexTypeInfo *tempType = aComplexType;
        tempType != 0 && tempType != exemplarComplexType;
        tempType = tempType->getBaseComplexTypeInfo())
    {
        if((tempType->getBlockSet() & anElementDerivationMethod) != 0)
            return false;
    }//for

    return true;
}