traverseschema.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,791 行 · 第 1/5 页
CPP
1,791 行
const XMLCh* nameSpace = getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE); if (XMLString::equals(nameSpace, fTargetNSURIString)) { reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::Import_1_1); return; } if ((!nameSpace || !*nameSpace) && fTargetNSURI == fEmptyNamespaceURI) { reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::Import_1_2); return; } // ------------------------------------------------------------------ // Resolve namespace to a grammar // ------------------------------------------------------------------ Grammar* aGrammar = 0; if (nameSpace) { XMLSchemaDescription* gramDesc = fGrammarResolver->getGrammarPool()->createSchemaDescription(nameSpace); Janitor<XMLSchemaDescription> janName(gramDesc); gramDesc->setContextType(XMLSchemaDescription::CONTEXT_IMPORT); gramDesc->setLocationHints(getElementAttValue(elem, SchemaSymbols::fgATT_SCHEMALOCATION)); aGrammar = fGrammarResolver->getGrammar(gramDesc); } bool grammarFound = (aGrammar && (aGrammar->getGrammarType() == Grammar::SchemaGrammarType)); if (grammarFound) { fSchemaInfo->addImportedNS(fURIStringPool->addOrFind(nameSpace)); } // ------------------------------------------------------------------ // Get 'schemaLocation' attribute // ------------------------------------------------------------------ const XMLCh* schemaLocation = getElementAttValue(elem, SchemaSymbols::fgATT_SCHEMALOCATION); //if (!schemaLocation || !*schemaLocation) { // return; //} // With new XMLEntityResolver, it may resolve the nameSpace so call resolveSchemaLocation... // ------------------------------------------------------------------ // Resolve schema location // ------------------------------------------------------------------ InputSource* srcToFill = resolveSchemaLocation(schemaLocation, XMLResourceIdentifier::SchemaImport, nameSpace); // Nothing to do if (!srcToFill) { return; } Janitor<InputSource> janSrc(srcToFill); const XMLCh* importURL = srcToFill->getSystemId(); SchemaInfo* importSchemaInfo = 0; if (nameSpace) importSchemaInfo = fSchemaInfoList->get(importURL, fURIStringPool->addOrFind(nameSpace)); else importSchemaInfo = fSchemaInfoList->get(importURL, fEmptyNamespaceURI); if (importSchemaInfo) { fSchemaInfo->addSchemaInfo(importSchemaInfo, SchemaInfo::IMPORT); return; } if (grammarFound) { return; } // ------------------------------------------------------------------ // Parse input source // ------------------------------------------------------------------ if (!fParser) fParser = new (fGrammarPoolMemoryManager) XSDDOMParser(0, fGrammarPoolMemoryManager, 0); fParser->setValidationScheme(XercesDOMParser::Val_Never); fParser->setDoNamespaces(true); fParser->setUserEntityHandler(fEntityHandler); fParser->setUserErrorReporter(fErrorReporter); // Should just issue warning if the schema is not found bool flag = srcToFill->getIssueFatalErrorIfNotFound(); srcToFill->setIssueFatalErrorIfNotFound(false); fParser->parse(*srcToFill) ; // Reset the InputSource srcToFill->setIssueFatalErrorIfNotFound(flag); if (fParser->getSawFatal() && fScanner->getExitOnFirstFatal()) reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError); // ------------------------------------------------------------------ // Get root element // ------------------------------------------------------------------ DOMDocument* document = fParser->getDocument(); if (document) { DOMElement* root = document->getDocumentElement(); if (!root) { return; } const XMLCh* targetNSURIString = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE); if (!XMLString::equals(targetNSURIString, nameSpace)) { reportSchemaError(root, XMLUni::fgXMLErrDomain, XMLErrs::ImportNamespaceDifference, schemaLocation, targetNSURIString, nameSpace); } else { // -------------------------------------------------------- // Preprocess new schema // -------------------------------------------------------- SchemaInfo* saveInfo = fSchemaInfo; fSchemaGrammar = new (fGrammarPoolMemoryManager) SchemaGrammar(fGrammarPoolMemoryManager); XMLSchemaDescription* gramDesc = (XMLSchemaDescription*) fSchemaGrammar->getGrammarDescription(); gramDesc->setContextType(XMLSchemaDescription::CONTEXT_IMPORT); gramDesc->setLocationHints(importURL); preprocessSchema(root, importURL); fPreprocessedNodes->put((void*) elem, fSchemaInfo); // -------------------------------------------------------- // Restore old schema information // -------------------------------------------------------- restoreSchemaInfo(saveInfo, SchemaInfo::IMPORT); } }}void TraverseSchema::traverseImport(const DOMElement* const elem) { SchemaInfo* importInfo = fPreprocessedNodes->get(elem); if (importInfo) { // -------------------------------------------------------- // Traverse new schema // -------------------------------------------------------- SchemaInfo* saveInfo = fSchemaInfo; restoreSchemaInfo(importInfo, SchemaInfo::IMPORT); doTraverseSchema(importInfo->getRoot()); // -------------------------------------------------------- // Restore old schema information // -------------------------------------------------------- restoreSchemaInfo(saveInfo, SchemaInfo::IMPORT); }}/** * Traverse redefine declaration * * <redefine> * schemaLocation = uriReference * {any attributes with non-schema namespace . . .}> * Content: (annotation | ( * attributeGroup | complexType | group | simpleType))* * </redefine> */void TraverseSchema::preprocessRedefine(const DOMElement* const redefineElem) { // ----------------------------------------------------------------------- // Check attributes // ----------------------------------------------------------------------- fAttributeCheck.checkAttributes( redefineElem, GeneralAttributeCheck::E_Redefine, this, true ); // First, we look through the children of redefineElem. Each one will // correspond to an element of the redefined schema that we need to // redefine. To do this, we rename the element of the redefined schema, // and rework the base or ref tag of the kid we're working on to refer to // the renamed group or derive the renamed type. Once we've done this, we // actually go through the schema being redefined and convert it to a // grammar. Only then do we run through redefineDecl's kids and put them // in the grammar. SchemaInfo* redefiningInfo = fSchemaInfo; if (!openRedefinedSchema(redefineElem)) { redefiningInfo->addFailedRedefine(redefineElem); return; } if (!fRedefineComponents) { fRedefineComponents = new (fMemoryManager) RefHash2KeysTableOf<XMLCh>(13, (bool) false, fMemoryManager); } SchemaInfo* redefinedInfo = fSchemaInfo; renameRedefinedComponents(redefineElem, redefiningInfo, redefinedInfo); // Now we have to preprocess our nicely-renamed schemas. if (fPreprocessedNodes->containsKey(redefineElem)) { fSchemaInfo = redefinedInfo; preprocessChildren(fSchemaInfo->getRoot()); } fSchemaInfo = redefiningInfo;}void TraverseSchema::traverseRedefine(const DOMElement* const redefineElem) { SchemaInfo* saveInfo = fSchemaInfo; SchemaInfo* redefinedInfo = fPreprocessedNodes->get(redefineElem); if (redefinedInfo) { // Now we have to march through our nicely-renamed schemas. When // we do these traversals other <redefine>'s may perhaps be // encountered; we leave recursion to sort this out. fSchemaInfo = redefinedInfo; processChildren(fSchemaInfo->getRoot()); fSchemaInfo = saveInfo; // Now traverse our own <redefine> processChildren(redefineElem); }}/** * Traverse the Choice, Sequence declaration * * <choice-sequqnce * id = ID * maxOccurs = (nonNegativeInteger | unbounded) : 1 * minOccurs = nonNegativeInteger : 1 * Content: (annotation?, (element | group | choice | sequence | any)*) * </choice-sequence> */ContentSpecNode*TraverseSchema::traverseChoiceSequence(const DOMElement* const elem, const int modelGroupType){ // ----------------------------------------------------------------------- // Check attributes // ----------------------------------------------------------------------- fAttributeCheck.checkAttributes( elem, GeneralAttributeCheck::E_Sequence, this, false, fNonXSAttList ); // ----------------------------------------------------------------------- // Process contents // ----------------------------------------------------------------------- DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true); if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) { fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); } Janitor<XSAnnotation> janAnnot(fAnnotation); ContentSpecNode* left = 0; ContentSpecNode* right = 0; bool hadContent = false; for (; child != 0; child = XUtil::getNextSiblingElement(child)) { ContentSpecNode* contentSpecNode = 0; bool seeParticle = false; const XMLCh* childName = child->getLocalName(); if (XMLString::equals(childName, SchemaSymbols::fgELT_ELEMENT)) { SchemaElementDecl* elemDecl = traverseElementDecl(child); if (!elemDecl ) continue; contentSpecNode = new (fGrammarPoolMemoryManager) ContentSpecNode ( elemDecl , fGrammarPoolMemoryManager ); seeParticle = true; } else if (XMLString::equals(childName, SchemaSymbols::fgELT_GROUP)) { XercesGroupInfo* grpInfo = traverseGroupDecl(child, false); if (!grpInfo) { continue; } contentSpecNode = grpInfo->getContentSpec(); if (!contentSpecNode) { continue; } if (contentSpecNode->hasAllContent()) { reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::AllContentLimited); continue; } contentSpecNode = new (fGrammarPoolMemoryManager) ContentSpecNode(*contentSpecNode); seeParticle = true; } else if (XMLString::equals(childName, SchemaSymbols::fgELT_CHOICE)) { contentSpecNode = traverseChoiceSequence(child,ContentSpecNode::Choice); seeParticle = true; } else if (XMLString::equals(childName, SchemaSymbols::fgELT_SEQUENCE)) { contentSpecNode = traverseChoiceSequence(child,ContentSpecNode::Sequence); seeParticle = true; } else if (XMLString::equals(childName, SchemaSymbols::fgELT_ANY)) { contentSpecNode = traverseAny(child); seeParticle = true; } else { reportSchemaError(child, XMLUni::fgValidityDomain, XMLValid::GroupContentRestricted, childName); } if (contentSpecNode) { hadContent = true; } if (seeParticle) { checkMinMax(contentSpecNode, child, Not_All_Context); } if (left == 0) { left = contentSpecNode; } else if (right == 0) { right = contentSpecNode; } else { left = new (fGrammarPoolMemoryManager) ContentSpecNode ( (ContentSpecNode::NodeTypes) modelGroupType , left , right , true , true , fGrammarPoolMemoryManager ); right = contentSpecNode; } } if (hadContent)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?