// ----------------------------------------------------------------------- // 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; }
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; }
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; }
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; }
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; }
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; }