traverseschema.cpp
来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,791 行 · 第 1/5 页
CPP
1,791 行
fCurrentScope = Grammar::TOP_LEVEL_SCOPE; fTargetNSURIString = fSchemaGrammar->getTargetNamespace(); fTargetNSURI = fURIStringPool->addOrFind(fTargetNSURIString); XMLSchemaDescription* gramDesc = (XMLSchemaDescription*) fSchemaGrammar->getGrammarDescription(); gramDesc->setTargetNamespace(fTargetNSURIString); fGrammarResolver->putGrammar(fSchemaGrammar); fAttributeCheck.setValidationContext(fSchemaGrammar->getValidationContext()); // Save current schema info SchemaInfo* currInfo = new (fMemoryManager) SchemaInfo(0, 0, 0, fTargetNSURI, fScopeCount, fNamespaceScope->increaseDepth(), XMLString::replicate(schemaURL, fGrammarPoolMemoryManager), fTargetNSURIString, schemaRoot, fGrammarPoolMemoryManager); if (fSchemaInfo) { fSchemaInfo->addSchemaInfo(currInfo, SchemaInfo::IMPORT); } fSchemaInfo = currInfo; fSchemaInfoList->put((void*) fSchemaInfo->getCurrentSchemaURL(), fSchemaInfo->getTargetNSURI(), fSchemaInfo); fSchemaInfo->addSchemaInfo(fSchemaInfo, SchemaInfo::INCLUDE); traverseSchemaHeader(schemaRoot); // preprocess chidren preprocessChildren(schemaRoot);}void TraverseSchema::traverseSchemaHeader(const DOMElement* const schemaRoot) { // Make sure that the root element is <xsd:schema> if (!XMLString::equals(schemaRoot->getLocalName(), SchemaSymbols::fgELT_SCHEMA)) { reportSchemaError(schemaRoot, XMLUni::fgXMLErrDomain, XMLErrs::InvalidXMLSchemaRoot); } // Make sure that the targetNamespace value is not empty string checkForEmptyTargetNamespace(schemaRoot); // ----------------------------------------------------------------------- // Check Attributes // ----------------------------------------------------------------------- fAttributeCheck.checkAttributes( schemaRoot, GeneralAttributeCheck::E_Schema, this , true, fSchemaInfo->getNonXSAttList() ); retrieveNamespaceMapping(schemaRoot); unsigned short elemAttrDefaultQualified = 0; if (XMLString::equals(schemaRoot->getAttribute(SchemaSymbols::fgATT_ELEMENTFORMDEFAULT), SchemaSymbols::fgATTVAL_QUALIFIED)) { elemAttrDefaultQualified |= Elem_Def_Qualified; } if (XMLString::equals(schemaRoot->getAttribute(SchemaSymbols::fgATT_ATTRIBUTEFORMDEFAULT), SchemaSymbols::fgATTVAL_QUALIFIED)) { elemAttrDefaultQualified |= Attr_Def_Qualified; } fSchemaInfo->setElemAttrDefaultQualified(elemAttrDefaultQualified); fSchemaInfo->setBlockDefault(parseBlockSet(schemaRoot, ES_Block, true)); fSchemaInfo->setFinalDefault(parseFinalSet(schemaRoot, ECS_Final, true));}XSAnnotation*TraverseSchema::traverseAnnotationDecl(const DOMElement* const annotationElem, ValueVectorOf<DOMNode*>* const nonXSAttList, const bool topLevel) { // ----------------------------------------------------------------------- // Check Attributes // ----------------------------------------------------------------------- fAttributeCheck.checkAttributes( annotationElem, GeneralAttributeCheck::E_Annotation, this, topLevel ); const XMLCh* contents = 0; for (DOMElement* child = XUtil::getFirstChildElement(annotationElem); child != 0; child = XUtil::getNextSiblingElement(child)) { const XMLCh* name = child->getLocalName(); if (XMLString::equals(name, SchemaSymbols::fgELT_APPINFO)) { DOMNode* textContent = child->getFirstChild(); if (textContent && textContent->getNodeType() == DOMNode::TEXT_NODE) contents = ((DOMText*) textContent)->getData(); fAttributeCheck.checkAttributes(child, GeneralAttributeCheck::E_Appinfo, this); } else if (XMLString::equals(name, SchemaSymbols::fgELT_DOCUMENTATION)) { DOMNode* textContent = child->getFirstChild(); if (textContent && textContent->getNodeType() == DOMNode::TEXT_NODE) contents = ((DOMText*) textContent)->getData(); fAttributeCheck.checkAttributes(child, GeneralAttributeCheck::E_Documentation, this); } else { reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidAnnotationContent); } } if (contents) { XSAnnotation* theAnnotation = 0; unsigned int nonXSAttSize = nonXSAttList->size(); if (nonXSAttSize) { int annotTokenStart = XMLString::patternMatch( contents, SchemaSymbols::fgELT_ANNOTATION); if (annotTokenStart == -1) // something is wrong return 0; // set annotation element fBuffer.set(contents, annotTokenStart + 10); for (unsigned int i=0; i<nonXSAttSize; i++) { DOMNode* attNode = nonXSAttList->elementAt(i); if (!XMLString::equals( annotationElem->getAttributeNS( attNode->getNamespaceURI(), attNode->getLocalName()) , XMLUni::fgZeroLenString) ) { continue; } fBuffer.append(chSpace); fBuffer.append(attNode->getNodeName()); fBuffer.append(chEqual); fBuffer.append(chDoubleQuote); processAttValue(attNode->getNodeValue(), fBuffer); fBuffer.append(chDoubleQuote); } // add remaining annotation content fBuffer.append(contents + annotTokenStart + 10); theAnnotation = new (fGrammarPoolMemoryManager) XSAnnotation(fBuffer.getRawBuffer(), fGrammarPoolMemoryManager); } else { theAnnotation = new (fGrammarPoolMemoryManager) XSAnnotation(contents, fGrammarPoolMemoryManager); } /*** * set line, col and systemId info ***/ theAnnotation->setLineCol( ((XSDElementNSImpl*)annotationElem)->getLineNo() , ((XSDElementNSImpl*)annotationElem)->getColumnNo() ); theAnnotation->setSystemId(fSchemaInfo->getCurrentSchemaURL()); return theAnnotation; } return 0;}/** * Traverse include * * <include * id = ID * schemaLocation = anyURI * {any attributes with non-schema namespace . . .}> * Content: (annotation?) * </include> */void TraverseSchema::preprocessInclude(const DOMElement* const elem) { // ----------------------------------------------------------------------- // Check attributes // ----------------------------------------------------------------------- fAttributeCheck.checkAttributes( elem, GeneralAttributeCheck::E_Include, this, true, fNonXSAttList); // ----------------------------------------------------------------------- // First, handle any ANNOTATION declaration // ----------------------------------------------------------------------- if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected); if (fAnnotation) fSchemaGrammar->addAnnotation(fAnnotation); else if (fScanner->getGenerateSyntheticAnnotations() && fNonXSAttList->size()) { fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); fSchemaGrammar->addAnnotation(fAnnotation); } // ----------------------------------------------------------------------- // Get 'schemaLocation' attribute // ----------------------------------------------------------------------- const XMLCh* schemaLocation = getElementAttValue(elem, SchemaSymbols::fgATT_SCHEMALOCATION); if (!schemaLocation || !*schemaLocation) { reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNoSchemaLocation, SchemaSymbols::fgELT_INCLUDE); return; } // ------------------------------------------------------------------ // Resolve schema location // ------------------------------------------------------------------ InputSource* srcToFill = resolveSchemaLocation(schemaLocation, XMLResourceIdentifier::SchemaInclude); Janitor<InputSource> janSrc(srcToFill); // Nothing to do if (!srcToFill) { return; } const XMLCh* includeURL = srcToFill->getSystemId(); SchemaInfo* includeSchemaInfo = fSchemaInfoList->get(includeURL, fTargetNSURI); if (includeSchemaInfo) { fSchemaInfo->addSchemaInfo(includeSchemaInfo, SchemaInfo::INCLUDE); 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) { const XMLCh* targetNSURIString = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE); // check to see if targetNameSpace is right if (*targetNSURIString && !XMLString::equals(targetNSURIString,fTargetNSURIString)){ reportSchemaError(root, XMLUni::fgXMLErrDomain, XMLErrs::IncludeNamespaceDifference, schemaLocation, targetNSURIString); return; } // if targetNamespace is empty, change it to includ'g schema // targetNamespace if (!*targetNSURIString && root->getAttributeNode(XMLUni::fgXMLNSString) == 0 && fTargetNSURI != fEmptyNamespaceURI) { root->setAttribute(XMLUni::fgXMLNSString, fTargetNSURIString); } // -------------------------------------------------------- // Update schema information with included schema // -------------------------------------------------------- SchemaInfo* saveInfo = fSchemaInfo; fSchemaInfo = new (fMemoryManager) SchemaInfo(0, 0, 0, fTargetNSURI, fScopeCount, fNamespaceScope->increaseDepth(), XMLString::replicate(includeURL, fGrammarPoolMemoryManager), fTargetNSURIString, root, fGrammarPoolMemoryManager); fSchemaInfoList->put((void*) fSchemaInfo->getCurrentSchemaURL(), fSchemaInfo->getTargetNSURI(), fSchemaInfo); fPreprocessedNodes->put((void*) elem, fSchemaInfo); saveInfo->addSchemaInfo(fSchemaInfo, SchemaInfo::INCLUDE); traverseSchemaHeader(root); preprocessChildren(root); fSchemaInfo = saveInfo; } }}void TraverseSchema::traverseInclude(const DOMElement* const elem) { SchemaInfo* includeInfo = fPreprocessedNodes->get(elem); if (includeInfo) { SchemaInfo* saveInfo = fSchemaInfo; fSchemaInfo = includeInfo; processChildren(includeInfo->getRoot()); fSchemaInfo = saveInfo; }}/** * Traverse import * * <import * id = ID * namespace = anyURI * schemaLocation = anyURI * {any attributes with non-schema namespace . . .}> * Content: (annotation?) * </import> */void TraverseSchema::preprocessImport(const DOMElement* const elem) { // ----------------------------------------------------------------------- // Check attributes // ----------------------------------------------------------------------- fAttributeCheck.checkAttributes( elem, GeneralAttributeCheck::E_Import, this, true, fNonXSAttList); // ----------------------------------------------------------------------- // First, handle any ANNOTATION declaration // ----------------------------------------------------------------------- if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected); if (fAnnotation) fSchemaGrammar->addAnnotation(fAnnotation); else if (fScanner->getGenerateSyntheticAnnotations() && fNonXSAttList->size()) { fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); fSchemaGrammar->addAnnotation(fAnnotation); } // ----------------------------------------------------------------------- // Handle 'namespace' attribute // -----------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?