xpathmatcher.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 400 行

CPP
400
字号
/* * Copyright 2001,2004 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Log: XPathMatcher.cpp,v $ * Revision 1.12  2004/09/08 13:56:59  peiyongz * Apache License Version 2.0 * * Revision 1.11  2004/01/29 11:52:32  cargilld * Code cleanup changes to get rid of various compiler diagnostic messages. * * Revision 1.10  2003/12/17 00:18:41  cargilld * Update to memory management so that the static memory manager (one used to call Initialize) is only for static data. * * Revision 1.9  2003/10/01 16:32:42  neilg * improve handling of out of memory conditions, bug #23415.  Thanks to David Cargill. * * Revision 1.8  2003/05/18 14:02:09  knoaman * Memory manager implementation: pass per instance manager. * * Revision 1.7  2003/05/15 18:59:34  knoaman * Partial implementation of the configurable memory manager. * * Revision 1.6  2003/01/13 20:16:52  knoaman * [Bug 16024] SchemaSymbols.hpp conflicts C++ Builder 6 dir.h * * Revision 1.5  2003/01/13 16:30:19  knoaman * [Bug 14469] Validator doesn't enforce xsd:key. * * Revision 1.4  2002/11/04 14:47:41  tng * C++ Namespace Support. * * Revision 1.3  2002/08/27 05:56:19  knoaman * Identity Constraint: handle case of recursive elements. * * Revision 1.2  2002/02/18 06:26:50  jberry * Quiet codewarrior compiler warnings * * Revision 1.1.1.1  2002/02/01 22:22:51  peiyongz * sane_include * * Revision 1.2  2001/11/15 17:10:19  knoaman * Particle derivation checking support. * * Revision 1.1  2001/11/02 14:08:40  knoaman * Add support for identity constraints. * */// ---------------------------------------------------------------------------//  Includes// ---------------------------------------------------------------------------#include <xercesc/validators/schema/identity/XPathMatcher.hpp>#include <xercesc/validators/schema/identity/XercesXPath.hpp>#include <xercesc/validators/schema/SchemaElementDecl.hpp>#include <xercesc/validators/schema/SchemaAttDef.hpp>#include <xercesc/validators/schema/SchemaSymbols.hpp>#include <xercesc/util/RuntimeException.hpp>#include <xercesc/util/OutOfMemoryException.hpp>XERCES_CPP_NAMESPACE_BEGIN// ---------------------------------------------------------------------------//  XPathMatcher: Constructors and Destructor// ---------------------------------------------------------------------------XPathMatcher::XPathMatcher( XercesXPath* const xpath                          , MemoryManager* const manager)    : fLocationPathSize(0)    , fMatched(0)    , fNoMatchDepth(0)    , fCurrentStep(0)    , fStepIndexes(0)    , fLocationPaths(0)    , fIdentityConstraint(0)    , fMemoryManager(manager){    try {        init(xpath);    }    catch(const OutOfMemoryException&)    {        throw;    }    catch(...) {        cleanUp();        throw;    }}XPathMatcher::XPathMatcher(XercesXPath* const xpath,                           IdentityConstraint* const ic,						   MemoryManager* const manager)    : fLocationPathSize(0)    , fMatched(0)    , fNoMatchDepth(0)    , fCurrentStep(0)    , fStepIndexes(0)    , fLocationPaths(0)    , fIdentityConstraint(ic)    , fMemoryManager(manager){    try {        init(xpath);    }    catch(const OutOfMemoryException&)    {        throw;    }    catch(...) {        cleanUp();        throw;    }}XPathMatcher::~XPathMatcher(){    cleanUp();}// ---------------------------------------------------------------------------//  XPathMatcher: Helper methods// ---------------------------------------------------------------------------void XPathMatcher::init(XercesXPath* const xpath) {    if (xpath) {        fLocationPaths = xpath->getLocationPaths();        fLocationPathSize = (fLocationPaths ? fLocationPaths->size() : 0);        if (fLocationPathSize) {            fStepIndexes = new (fMemoryManager) RefVectorOf<ValueStackOf<int> >(fLocationPathSize, true, fMemoryManager);            fCurrentStep = (int*) fMemoryManager->allocate            (                fLocationPathSize * sizeof(int)            );//new int[fLocationPathSize];            fNoMatchDepth = (int*) fMemoryManager->allocate            (                fLocationPathSize * sizeof(int)            );//new int[fLocationPathSize];            fMatched = (int*) fMemoryManager->allocate            (                fLocationPathSize * sizeof(int)            );//new int[fLocationPathSize];            for(unsigned int i=0; i < fLocationPathSize; i++) {                fStepIndexes->addElement(new (fMemoryManager) ValueStackOf<int>(8, fMemoryManager));            }        }    }}// ---------------------------------------------------------------------------//  XPathMatcher: XMLDocumentHandler methods// ---------------------------------------------------------------------------void XPathMatcher::startDocumentFragment() {    for(unsigned int i = 0; i < fLocationPathSize; i++) {        fStepIndexes->elementAt(i)->removeAllElements();        fCurrentStep[i] = 0;        fNoMatchDepth[i] = 0;        fMatched[i] = 0;    }}void XPathMatcher::startElement(const XMLElementDecl& elemDecl,                                const unsigned int urlId,                                const XMLCh* const elemPrefix,								const RefVectorOf<XMLAttr>& attrList,                                const unsigned int attrCount) {    for (int i = 0; i < (int) fLocationPathSize; i++) {        // push context        int startStep = fCurrentStep[i];        fStepIndexes->elementAt(i)->push(startStep);        // try next xpath, if not matching        if ((fMatched[i] & XP_MATCHED_D) == XP_MATCHED || fNoMatchDepth[i] > 0) {            fNoMatchDepth[i]++;            continue;        }        if((fMatched[i] & XP_MATCHED_D) == XP_MATCHED_D) {            fMatched[i] = XP_MATCHED_DP;        }        // consume self::node() steps        XercesLocationPath* locPath = fLocationPaths->elementAt(i);        int stepSize = locPath->getStepSize();        while (fCurrentStep[i] < stepSize &&               locPath->getStep(fCurrentStep[i])->getAxisType() == XercesStep::SELF) {            fCurrentStep[i]++;        }        if (fCurrentStep[i] == stepSize) {            fMatched[i] = XP_MATCHED;            continue;        }        // now if the current step is a descendant step, we let the next        // step do its thing; if it fails, we reset ourselves        // to look at this step for next time we're called.        // so first consume all descendants:        int descendantStep = fCurrentStep[i];        while (fCurrentStep[i] < stepSize &&               locPath->getStep(fCurrentStep[i])->getAxisType() == XercesStep::DESCENDANT) {            fCurrentStep[i]++;        }        bool sawDescendant = fCurrentStep[i] > descendantStep;        if (fCurrentStep[i] == stepSize) {            fNoMatchDepth[i]++;            continue;        }        // match child::... step, if haven't consumed any self::node()        if ((fCurrentStep[i] == startStep || fCurrentStep[i] > descendantStep) &&            locPath->getStep(fCurrentStep[i])->getAxisType() == XercesStep::CHILD) {            XercesStep* step = locPath->getStep(fCurrentStep[i]);            XercesNodeTest* nodeTest = step->getNodeTest();            if (nodeTest->getType() == XercesNodeTest::QNAME) {                QName elemQName(elemPrefix, elemDecl.getElementName()->getLocalPart(), urlId, fMemoryManager);//                if (!(*(nodeTest->getName()) == *(elemDecl.getElementName()))) {                if (!(*(nodeTest->getName()) == elemQName)) {                    if(fCurrentStep[i] > descendantStep) {                        fCurrentStep[i] = descendantStep;                        continue;                    }                    fNoMatchDepth[i]++;                    continue;                }            }            fCurrentStep[i]++;        }        if (fCurrentStep[i] == stepSize) {            if (sawDescendant) {                fCurrentStep[i] = descendantStep;                fMatched[i] = XP_MATCHED_D;            }            else {                fMatched[i] = XP_MATCHED;            }            continue;        }        // match attribute::... step        if (fCurrentStep[i] < stepSize &&            locPath->getStep(fCurrentStep[i])->getAxisType() == XercesStep::ATTRIBUTE) {            if (attrCount) {                XercesNodeTest* nodeTest = locPath->getStep(fCurrentStep[i])->getNodeTest();                for (unsigned int attrIndex = 0; attrIndex < attrCount; attrIndex++) {                    const XMLAttr* curDef = attrList.elementAt(attrIndex);                    if (nodeTest->getType() != XercesNodeTest::QNAME ||                        (*(nodeTest->getName()) == *(curDef->getAttName()))) {                        fCurrentStep[i]++;                        if (fCurrentStep[i] == stepSize) {                            fMatched[i] = XP_MATCHED_A;                            int j=0;                            for(; j<i && ((fMatched[j] & XP_MATCHED) != XP_MATCHED); j++) ;                            if(j == i) {                                SchemaAttDef* attDef = ((SchemaElementDecl&) elemDecl).getAttDef(curDef->getName(), curDef->getURIId());                                DatatypeValidator* dv = (attDef) ? attDef->getDatatypeValidator() : 0;                                matched(curDef->getValue(), dv, false);                            }                        }                        break;                    }                }            }            if ((fMatched[i] & XP_MATCHED) != XP_MATCHED) {                if(fCurrentStep[i] > descendantStep) {                    fCurrentStep[i] = descendantStep;                    continue;                }                fNoMatchDepth[i]++;            }        }    }}void XPathMatcher::endElement(const XMLElementDecl& elemDecl,                              const XMLCh* const elemContent) {    for(int i = 0; i < (int) fLocationPathSize; i++) {        // go back a step        fCurrentStep[i] = fStepIndexes->elementAt(i)->pop();        // don't do anything, if not matching        if (fNoMatchDepth[i] > 0) {            fNoMatchDepth[i]--;        }        // signal match, if appropriate        else {            int j=0;            for(; j<i && ((fMatched[j] & XP_MATCHED) != XP_MATCHED); j++) ;            if (j < i || (fMatched[j] == 0)                || ((fMatched[j] & XP_MATCHED_A) == XP_MATCHED_A))				continue;            DatatypeValidator* dv = ((SchemaElementDecl*) &elemDecl)->getDatatypeValidator();            bool isNillable = (((SchemaElementDecl *) &elemDecl)->getMiscFlags() & SchemaSymbols::XSD_NILLABLE) != 0;            matched(elemContent, dv, isNillable);            fMatched[i] = 0;        }    }}// ---------------------------------------------------------------------------//  XPathMatcher: Match methods// ---------------------------------------------------------------------------int XPathMatcher::isMatched() {    // xpath has been matched if any one of the members of the union have matched.    for (int i=0; i < (int) fLocationPathSize; i++) {        if (((fMatched[i] & XP_MATCHED) == XP_MATCHED)            && ((fMatched[i] & XP_MATCHED_DP) != XP_MATCHED_DP))            return fMatched[i];    }    return 0;}void XPathMatcher::matched(const XMLCh* const,                           DatatypeValidator* const,                           const bool) {    return;}// ---------------------------------------------------------------------------//  XPathMatcher: Match methods// ---------------------------------------------------------------------------int XPathMatcher::getInitialDepth() const{    ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Regex_NotSupported, fMemoryManager);    return 0; // to make some compilers happy}XERCES_CPP_NAMESPACE_END/**  * End of file XPathMatcher.cpp  */

⌨️ 快捷键说明

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