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