schemavalidator.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,621 行 · 第 1/5 页

CPP
1,621
字号
                    }                }            }        }    }}// ---------------------------------------------------------------------------//  SchemaValidator: Particle Derivation Checking// ---------------------------------------------------------------------------void SchemaValidator::checkParticleDerivation(SchemaGrammar* const currentGrammar,                                              const ComplexTypeInfo* const curTypeInfo) {    ComplexTypeInfo* baseTypeInfo = 0;    ContentSpecNode* curSpecNode = 0;    if (curTypeInfo->getDerivedBy() == SchemaSymbols::XSD_RESTRICTION        && ((baseTypeInfo = curTypeInfo->getBaseComplexTypeInfo()) != 0)        && ((curSpecNode = curTypeInfo->getContentSpec()) != 0)) {        try {            checkParticleDerivationOk(currentGrammar, curSpecNode,                                      curTypeInfo->getScopeDefined(),                                      baseTypeInfo->getContentSpec(),                                      baseTypeInfo->getScopeDefined(), baseTypeInfo);        }        catch (const XMLException& excep) {            fSchemaErrorReporter.emitError(XMLErrs::DisplayErrorMessage, XMLUni::fgXMLErrDomain, curTypeInfo->getLocator(), excep.getMessage(), 0, 0, 0, fMemoryManager);        }    }}ContentSpecNode* SchemaValidator::getNonUnaryGroup(ContentSpecNode* const pNode) {    int pNodeType = (pNode->getType() & 0x0f);    if (pNodeType == ContentSpecNode::Leaf        || pNodeType == ContentSpecNode::Any        || pNodeType == ContentSpecNode::Any_Other        || pNodeType == ContentSpecNode::Any_NS)        return pNode;    if (pNode->getMinOccurs() == 1 && pNode->getMaxOccurs() == 1        && pNode->getFirst() && !pNode->getSecond())        return getNonUnaryGroup(pNode->getFirst());    return pNode;}void SchemaValidator::checkParticleDerivationOk(SchemaGrammar* const aGrammar,                                                ContentSpecNode* const curNode,                                                const int derivedScope,                                                ContentSpecNode* const baseNode,                                                const int baseScope,                                                const ComplexTypeInfo* const baseInfo,                                                const bool toCheckOccurence) {    // Check for pointless occurrences of all, choice, sequence.  The result is    // the contentspec which is not pointless. If the result is a non-pointless    // group, Vector is filled  in with the children of interest    if (curNode && !baseNode)        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::PD_EmptyBase, fMemoryManager);    if (!curNode)        return;    ContentSpecNode* curSpecNode = getNonUnaryGroup(curNode);    ContentSpecNode* baseSpecNode = getNonUnaryGroup(baseNode);    ValueVectorOf<ContentSpecNode*> curVector(8, fMemoryManager);    ValueVectorOf<ContentSpecNode*> baseVector(8, fMemoryManager);    ContentSpecNode::NodeTypes curNodeType = curSpecNode->getType();    ContentSpecNode::NodeTypes baseNodeType = baseSpecNode->getType();    if ((curNodeType & 0x0f) == ContentSpecNode::Sequence ||        (curNodeType & 0x0f) == ContentSpecNode::Choice ||        curNodeType == ContentSpecNode::All) {        curSpecNode = checkForPointlessOccurrences(curSpecNode, curNodeType, &curVector);    }    if ((baseNodeType & 0x0f) == ContentSpecNode::Sequence ||        (baseNodeType & 0x0f) == ContentSpecNode::Choice ||        baseNodeType == ContentSpecNode::All) {        baseSpecNode = checkForPointlessOccurrences(baseSpecNode, baseNodeType, &baseVector);    }    curNodeType = curSpecNode->getType();    baseNodeType = baseSpecNode->getType();    switch (curNodeType & 0x0f) {    case ContentSpecNode::Leaf:        {            switch (baseNodeType & 0x0f) {            case ContentSpecNode::Leaf:                {                    checkNameAndTypeOK(aGrammar, curSpecNode, derivedScope, baseSpecNode, baseScope, baseInfo);                    return;                }            case ContentSpecNode::Any:            case ContentSpecNode::Any_Other:            case ContentSpecNode::Any_NS:                {                    checkNSCompat(curSpecNode, baseSpecNode, toCheckOccurence);                    return;                }            case ContentSpecNode::Choice:            case ContentSpecNode::Sequence:            case ContentSpecNode::All:                {                    checkRecurseAsIfGroup(aGrammar, curSpecNode, derivedScope,                                          baseSpecNode, baseScope, &baseVector, baseInfo);                    return;                }            default:                {                    ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::PD_InvalidContentType, fMemoryManager);                }            }		        }    case ContentSpecNode::Any:    case ContentSpecNode::Any_Other:    case ContentSpecNode::Any_NS:        {            switch (baseNodeType & 0x0f) {            case ContentSpecNode::Any:            case ContentSpecNode::Any_Other:            case ContentSpecNode::Any_NS:                {                     checkNSSubset(curSpecNode, baseSpecNode);                     return;                }            case ContentSpecNode::Choice:            case ContentSpecNode::Sequence:            case ContentSpecNode::All:            case ContentSpecNode::Leaf:                {                    ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::PD_ForbiddenRes1, fMemoryManager);                }            default:                {                    ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::PD_InvalidContentType, fMemoryManager);                }            }        }    case ContentSpecNode::All:        {            switch (baseNodeType & 0x0f) {            case ContentSpecNode::Any:            case ContentSpecNode::Any_Other:            case ContentSpecNode::Any_NS:                {                    checkNSRecurseCheckCardinality(aGrammar, curSpecNode, &curVector, derivedScope, baseSpecNode, toCheckOccurence);                    return;                }            case ContentSpecNode::All:                {                    checkRecurse(aGrammar, curSpecNode, derivedScope, &curVector,                                 baseSpecNode, baseScope, &baseVector, baseInfo);                    return;                }            case ContentSpecNode::Choice:            case ContentSpecNode::Sequence:            case ContentSpecNode::Leaf:                {                    ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::PD_ForbiddenRes2, fMemoryManager);                }            default:                {                    ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::PD_InvalidContentType, fMemoryManager);                }            }        }    case ContentSpecNode::Choice:        {            switch (baseNodeType & 0x0f) {            case ContentSpecNode::Any:            case ContentSpecNode::Any_Other:            case ContentSpecNode::Any_NS:                {                    checkNSRecurseCheckCardinality(aGrammar, curSpecNode, &curVector, derivedScope, baseSpecNode, toCheckOccurence);                    return;                }            case ContentSpecNode::Choice:                {                    checkRecurse(aGrammar, curSpecNode, derivedScope, &curVector,                                 baseSpecNode, baseScope, &baseVector, baseInfo, true);                    return;                }            case ContentSpecNode::All:            case ContentSpecNode::Sequence:            case ContentSpecNode::Leaf:                {                    ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::PD_ForbiddenRes3, fMemoryManager);                }            default:                {                    ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::PD_InvalidContentType, fMemoryManager);                }            }        }    case ContentSpecNode::Sequence:        {            switch (baseNodeType & 0x0f) {            case ContentSpecNode::Any:            case ContentSpecNode::Any_Other:            case ContentSpecNode::Any_NS:                {                    checkNSRecurseCheckCardinality(aGrammar, curSpecNode, &curVector, derivedScope, baseSpecNode, toCheckOccurence);                    return;                }            case ContentSpecNode::All:                {                    checkRecurseUnordered(aGrammar, curSpecNode, &curVector, derivedScope,                                          baseSpecNode, &baseVector, baseScope, baseInfo);                    return;                }            case ContentSpecNode::Sequence:                {                    checkRecurse(aGrammar, curSpecNode, derivedScope, &curVector,                                 baseSpecNode, baseScope, &baseVector, baseInfo);                    return;                }            case ContentSpecNode::Choice:                {                    checkMapAndSum(aGrammar, curSpecNode, &curVector, derivedScope,                                   baseSpecNode, &baseVector, baseScope, baseInfo);                    return;                }            case ContentSpecNode::Leaf:                {                    ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::PD_ForbiddenRes4, fMemoryManager);                }            default:                {                    ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::PD_InvalidContentType, fMemoryManager);                }            }        }    }}ContentSpecNode*SchemaValidator::checkForPointlessOccurrences(ContentSpecNode* const specNode,                                              const ContentSpecNode::NodeTypes nodeType,                                              ValueVectorOf<ContentSpecNode*>* const nodes) {    ContentSpecNode* rightNode = specNode->getSecond();    int min = specNode->getMinOccurs();    int max = specNode->getMaxOccurs();    if (!rightNode) {         gatherChildren(nodeType, specNode->getFirst(), nodes);         if (nodes->size() == 1 && min == 1 && max == 1) {            return nodes->elementAt(0);        }        return specNode;    }    gatherChildren(nodeType, specNode->getFirst(), nodes);    gatherChildren(nodeType, rightNode, nodes);    return specNode;}void SchemaValidator::gatherChildren(const ContentSpecNode::NodeTypes parentNodeType,                                    ContentSpecNode* const specNode,                                    ValueVectorOf<ContentSpecNode*>* const nodes) {    if (!specNode) {        return;    }    int min = specNode->getMinOccurs();    int max = specNode->getMaxOccurs();    ContentSpecNode::NodeTypes nodeType = specNode->getType();    ContentSpecNode* rightNode = specNode->getSecond();    if (nodeType == ContentSpecNode::Leaf ||        (nodeType & 0x0f) == ContentSpecNode::Any ||        (nodeType & 0x0f) == ContentSpecNode::Any_NS ||        (nodeType & 0x0f) == ContentSpecNode::Any_Other) {        nodes->addElement(specNode);    }    else if (min !=1 || max != 1) {        nodes->addElement(specNode);    }    else if (!rightNode) {        gatherChildren(nodeType, specNode->getFirst(), nodes);    }    else if ((parentNodeType & 0x0f) == (nodeType & 0x0f)) {        gatherChildren(nodeType, specNode->getFirst(), nodes);        gatherChildren(nodeType, rightNode, nodes);    }    else {        nodes->addElement(specNode);    }}voidSchemaValidator::checkNSCompat(const ContentSpecNode* const derivedSpecNode,                               const ContentSpecNode* const baseSpecNode,                               const bool toCheckOccurence) {    // check Occurrence ranges    if (toCheckOccurence &&        !isOccurrenceRangeOK(derivedSpecNode->getMinOccurs(), derivedSpecNode->getMaxOccurs(),                             baseSpecNode->getMinOccurs(), baseSpecNode->getMaxOccurs())) {        ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::PD_OccurRangeE,                  derivedSpecNode->getElement()->getLocalPart(), fMemoryManager);    }    // check wildcard subset    if (!wildcardEltAllowsNamespace(baseSpecNode, derivedSpecNode->getElement()->getURI())) {        ThrowXMLwithMemMgr1(RuntimeException, XMLExcepts::PD_NSCompat1,                  derivedSpecNode->getElement()->getLocalPart(), fMemoryManager);    }}b

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?