traverseschema.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,791 行 · 第 1/5 页
CPP
1,791 行
{ left = new (fGrammarPoolMemoryManager) ContentSpecNode ( ((ContentSpecNode::NodeTypes) modelGroupType) == ContentSpecNode::Choice ? ContentSpecNode::ModelGroupChoice : ContentSpecNode::ModelGroupSequence , left , right , true , true , fGrammarPoolMemoryManager ); if (!janAnnot.isDataNull()) fSchemaGrammar->putAnnotation(left, janAnnot.release()); } return left;}/** * Traverse SimpleType declaration: * <simpleType * id = ID * name = NCName> * Content: (annotation? , ((list | restriction | union))) * </simpleType> * * traverse <list>|<restriction>|<union> */DatatypeValidator*TraverseSchema::traverseSimpleTypeDecl(const DOMElement* const childElem, const bool topLevel, int baseRefContext){ // ------------------------------------------------------------------ // Process contents // ------------------------------------------------------------------ const XMLCh* name = getElementAttValue(childElem,SchemaSymbols::fgATT_NAME); bool nameEmpty = (!name || !*name); if (topLevel && nameEmpty) { reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement, SchemaSymbols::fgELT_SIMPLETYPE); return 0; } if (nameEmpty) { // anonymous simpleType name = genAnonTypeName(fgAnonSNamePrefix); } else if (!XMLString::isValidNCName(name)) { reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, SchemaSymbols::fgELT_SIMPLETYPE, name); return 0; } fBuffer.set(fTargetNSURIString); fBuffer.append(chComma); fBuffer.append(name); unsigned int fullTypeNameId = fStringPool->addOrFind(fBuffer.getRawBuffer()); const XMLCh* fullName = fStringPool->getValueForId(fullTypeNameId); //check if we have already traversed the same simpleType decl DatatypeValidator* dv = fDatatypeRegistry->getDatatypeValidator(fullName); if (!dv) { // ------------------------------------------------------------------- // Check attributes // ------------------------------------------------------------------- unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_SimpleTypeGlobal : GeneralAttributeCheck::E_SimpleTypeLocal; fAttributeCheck.checkAttributes( childElem, scope, this, topLevel, fNonXSAttList ); // Circular constraint checking if (fCurrentTypeNameStack->containsElement(fullTypeNameId)) { reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, name); return 0; } fCurrentTypeNameStack->addElement(fullTypeNameId); // Get 'final' values int finalSet = parseFinalSet(childElem, S_Final); // annotation?,(list|restriction|union) DOMElement* content= checkContent( childElem, XUtil::getFirstChildElement(childElem), false); if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) { fAnnotation = generateSyntheticAnnotation(childElem, fNonXSAttList); } Janitor<XSAnnotation> janAnnot(fAnnotation); if (content == 0) { reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::EmptySimpleTypeContent); popCurrentTypeNameStack(); return 0; } const XMLCh* varietyName = content->getLocalName(); // Remark: some code will be repeated in list|restriction| union but it // is cleaner that way if (XMLString::equals(varietyName, SchemaSymbols::fgELT_LIST)) { //traverse List if ((baseRefContext & SchemaSymbols::XSD_LIST) != 0) { reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AtomicItemType); popCurrentTypeNameStack(); return 0; } dv = traverseByList(childElem, content, name, fullName, finalSet, &janAnnot); } else if (XMLString::equals(varietyName, SchemaSymbols::fgELT_RESTRICTION)) { //traverse Restriction dv = traverseByRestriction(childElem, content, name, fullName, finalSet, &janAnnot); } else if (XMLString::equals(varietyName, SchemaSymbols::fgELT_UNION)) { //traverse union dv = traverseByUnion(childElem, content, name, fullName, finalSet, baseRefContext, &janAnnot); } else { reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::FeatureUnsupported, varietyName); popCurrentTypeNameStack(); } if (dv) { if (nameEmpty) dv->setAnonymous(); if (!janAnnot.isDataNull()) fSchemaGrammar->putAnnotation(dv, janAnnot.release()); } } return dv;}/** * Traverse ComplexType Declaration - CR Implementation. * * <complexType * abstract = boolean * block = #all or (possibly empty) subset of {extension, restriction} * final = #all or (possibly empty) subset of {extension, restriction} * id = ID * mixed = boolean : false * name = NCName> * Content: (annotation? , (simpleContent | complexContent | * ( (group | all | choice | sequence)? , * ( (attribute | attributeGroup)* , anyAttribute?)))) * </complexType> */int TraverseSchema::traverseComplexTypeDecl(const DOMElement* const elem, const bool topLevel, const XMLCh* const recursingTypeName) { // Get the attributes of the complexType const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME); bool isAnonymous = false; if (!name || !*name) { if (topLevel) { reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TopLevelNoNameComplexType); return -1; } if (recursingTypeName) name = recursingTypeName; else { name = genAnonTypeName(fgAnonCNamePrefix); isAnonymous = true; } } if (!XMLString::isValidNCName(name)) { //REVISIT - Should we return or continue and save type with wrong name? reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, SchemaSymbols::fgELT_COMPLEXTYPE, name); return -1; } // ------------------------------------------------------------------ // Check if the type has already been registered // ------------------------------------------------------------------ fBuffer.set(fTargetNSURIString); fBuffer.append(chComma); fBuffer.append(name); int typeNameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer()); const XMLCh* fullName = fStringPool->getValueForId(typeNameIndex); ComplexTypeInfo* typeInfo = 0; if (topLevel || recursingTypeName) { typeInfo = fComplexTypeRegistry->get(fullName); if (typeInfo && !typeInfo->getPreprocessed()) { return typeNameIndex; } } // ----------------------------------------------------------------------- // Check Attributes // ----------------------------------------------------------------------- unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_ComplexTypeGlobal : GeneralAttributeCheck::E_ComplexTypeLocal; fAttributeCheck.checkAttributes(elem, scope, this, topLevel, fNonXSAttList); // ----------------------------------------------------------------------- // Create a new instance // ----------------------------------------------------------------------- bool preProcessFlag = (typeInfo) ? typeInfo->getPreprocessed() : false; unsigned int previousCircularCheckIndex = fCircularCheckIndex; int previousScope = fCurrentScope; if (preProcessFlag) { fCurrentScope = typeInfo->getScopeDefined(); typeInfo->setPreprocessed(false); } else { // ------------------------------------------------------------------ // Register the type // ------------------------------------------------------------------ typeInfo = new (fGrammarPoolMemoryManager) ComplexTypeInfo(fGrammarPoolMemoryManager); if(isAnonymous) { typeInfo->setAnonymous(); } fCurrentScope = fScopeCount++; fComplexTypeRegistry->put((void*) fullName, typeInfo); typeInfo->setTypeName(fullName); typeInfo->setScopeDefined(fCurrentScope); if (fFullConstraintChecking) { XSDLocator* aLocator = new (fGrammarPoolMemoryManager) XSDLocator(); aLocator->setValues(fStringPool->getValueForId(fStringPool->addOrFind(fSchemaInfo->getCurrentSchemaURL())), 0, ((XSDElementNSImpl*) elem)->getLineNo(), ((XSDElementNSImpl*) elem)->getColumnNo()); typeInfo->setLocator(aLocator); } } fCurrentTypeNameStack->addElement(typeNameIndex); ComplexTypeInfo* saveTypeInfo = fCurrentComplexType; fCurrentComplexType = typeInfo; // ------------------------------------------------------------------ // First, handle any ANNOTATION declaration and get next child // ------------------------------------------------------------------ DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true); if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) { fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); } Janitor<XSAnnotation> janAnnot(fAnnotation); // ------------------------------------------------------------------ // Process the content of the complex type declaration // ------------------------------------------------------------------ try { const XMLCh* mixedVal = getElementAttValue(elem,SchemaSymbols::fgATT_MIXED); bool isMixed = false; if ((mixedVal && *mixedVal) && (XMLString::equals(SchemaSymbols::fgATTVAL_TRUE, mixedVal) || XMLString::equals(fgValueOne, mixedVal))) { isMixed = true; } if (child == 0) { // EMPTY complexType with complexContent processComplexContent(elem, name, child, typeInfo, 0, isMixed); } else { const XMLCh* childName = child->getLocalName(); if (XMLString::equals(childName, SchemaSymbols::fgELT_SIMPLECONTENT)) { // SIMPLE CONTENT element traverseSimpleContentDecl(name, fullName, child, typeInfo, &janAnnot); if (XUtil::getNextSiblingElement(child) != 0) { reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildFollowingSimpleContent); } } else if (XMLString::equals(childName, SchemaSymbols::fgELT_COMPLEXCONTENT)) { // COMPLEX CONTENT element traverseComplexContentDecl(name, child, typeInfo, isMixed, &janAnnot); if (XUtil::getNextSiblingElement(child) != 0) { reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildFollowingConplexContent); } } else if (fCurrentGroupInfo) { typeInfo->setPreprocessed(true); } else { // We must have .... // GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes // Note that it's possible that only attributes are specified. processComplexContent(elem, name, child, typeInfo, 0, isMixed); } } } catch(const TraverseSchema::ExceptionCodes aCode) { if (aCode == TraverseSchema::InvalidComplexTypeInfo) defaultComplexTypeInfo(typeInfo); else if (aCode == TraverseSchema::RecursingElement) typeInfo->setPreprocessed(); } // ------------------------------------------------------------------ // Finish the setup of the typeInfo // ------------------------------------------------------------------ if (!preProcessFlag) { const XMLCh* abstractAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT); int blockSet = parseBlockSet(elem, C_Block); int finalSet = parseFinalSet(elem, EC_Final); typeInfo->setBlockSet(blockSet); typeInfo->setFinalSet(finalSet); if ((abstractAttVal && *abstractAttVal) && (XMLString::equals(abstractAttVal, SchemaSymbols::fgATTVAL_TRUE) || XMLString::equals(abstractAttVal, fgValueOne))) { typeInfo->setAbstract(true); } else { typeInfo->setAbstract(false); } } // Store Annotation if (!janAnnot.isDataNull()) fSchemaGrammar->putAnnotation(typeInfo, janAnnot.release()); // ------------------------------------------------------------------ // Before exiting, restore the scope, mainly for nested anonymous types // ------------------------------------------------------------------ popCurrentTypeNameStack(); fCircularCheckIndex = previousCircularCheckIndex; fCurrentScope = previousScope; fCurrentComplexType = saveTypeInfo;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?