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 + -
显示快捷键?