domnodeiteratorimpl.cpp

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

CPP
363
字号
/* * Copyright 2001-2002,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. *//* * $Id: DOMNodeIteratorImpl.cpp,v 1.8 2004/09/08 13:55:52 peiyongz Exp $ *///////////////////////////////////////////////////////////////////////// DOMNodeIteratorImpl.cpp: implementation of the DOMNodeIteratorImpl class.////////////////////////////////////////////////////////////////////////#include "DOMNodeIteratorImpl.hpp"#include "DOMDocumentImpl.hpp"#include <xercesc/dom/DOMDocument.hpp>#include <xercesc/dom/DOMException.hpp>XERCES_CPP_NAMESPACE_BEGIN//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////DOMNodeIteratorImpl::DOMNodeIteratorImpl (DOMDocument* doc,                                    DOMNode* root,                                    unsigned long whatToShow,                                    DOMNodeFilter* nodeFilter,                                    bool expandEntityRef):   fRoot(root),    fDocument(doc),    fWhatToShow(whatToShow),    fNodeFilter(nodeFilter),    fExpandEntityReferences(expandEntityRef),    fDetached(false),    fCurrentNode(0),    fForward(true)    {	}DOMNodeIteratorImpl::DOMNodeIteratorImpl ( const DOMNodeIteratorImpl& toCopy)    :   fRoot(toCopy.fRoot),    fDocument(toCopy.fDocument),    fWhatToShow(toCopy.fWhatToShow),    fNodeFilter(toCopy.fNodeFilter),    fExpandEntityReferences(toCopy.fExpandEntityReferences),    fDetached(toCopy.fDetached),    fCurrentNode(toCopy.fCurrentNode),    fForward(toCopy.fForward){}DOMNodeIteratorImpl& DOMNodeIteratorImpl::operator= (const DOMNodeIteratorImpl& other) {    fRoot                   = other.fRoot;    fCurrentNode            = other.fRoot;    fWhatToShow             = other.fWhatToShow;    fNodeFilter             = other.fNodeFilter;    fForward                = other.fForward;    fDetached               = other.fDetached;    fExpandEntityReferences = other.fExpandEntityReferences;    fDocument               = other.fDocument;    return *this;}DOMNodeIteratorImpl::~DOMNodeIteratorImpl (){	fDetached = false;}void DOMNodeIteratorImpl::detach (){	fDetached = true;   ((DOMDocumentImpl *)fDocument)->removeNodeIterator(this);}DOMNode* DOMNodeIteratorImpl::getRoot() {    return fRoot;}// Implementation Note: Note that the iterator looks at whatToShow// and filter values at each call, and therefore one _could_ add// setters for these values and alter them while iterating!/** Return the whatToShow value */unsigned long DOMNodeIteratorImpl::getWhatToShow () {    return fWhatToShow;}/** Return the filter */DOMNodeFilter* DOMNodeIteratorImpl::getFilter () {    return fNodeFilter;}/** Get the expandEntity reference flag. */bool DOMNodeIteratorImpl::getExpandEntityReferences(){    return fExpandEntityReferences;}/** Return the next DOMNode* in the Iterator. The node is the next node in *  depth-first order which also passes the filter, and whatToShow. *  A 0 return means either that */DOMNode* DOMNodeIteratorImpl::nextNode () {	if (fDetached)		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);    // if root is 0 there is no next node->    if (!fRoot)			return 0;    DOMNode* aNextNode = fCurrentNode;    bool accepted = false; // the next node has not been accepted.    while (!accepted) {        // if last direction is not forward, repeat node->        if (!fForward && (aNextNode != 0)) {            //System.out.println("nextNode():!fForward:"+fCurrentNode.getNodeName());            aNextNode = fCurrentNode;        } else {        // else get the next node via depth-first            aNextNode = nextNode(aNextNode, true);        }        fForward = true; //REVIST: should direction be set forward before 0 check?        // nothing in the list. return 0.        if (!aNextNode) return 0;        // does node pass the filters and whatToShow?        accepted = acceptNode(aNextNode);        if (accepted) {            // if so, then the node is the current node->            fCurrentNode = aNextNode;            return fCurrentNode;        }    }    // no nodes, or no accepted nodes.    return 0;}/** Return the previous Node in the Iterator. The node is the next node in *  _backwards_ depth-first order which also passes the filter, and whatToShow. */DOMNode* DOMNodeIteratorImpl::previousNode () {	if (fDetached)		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);		    // if the root is 0, or the current node is 0, return 0.    if (!fRoot || !fCurrentNode) return 0;    DOMNode* aPreviousNode = fCurrentNode;    bool accepted = false;    while (!accepted) {        if (fForward && (aPreviousNode != 0)) {            //repeat last node->            aPreviousNode = fCurrentNode;        } else {            // get previous node in backwards depth first order.            aPreviousNode = previousNode(aPreviousNode);        }        // we are going backwards        fForward = false;        // if the new previous node is 0, we're at head or past the root,        // so return 0.        if (!aPreviousNode) return 0;        // check if node passes filters and whatToShow.        accepted = acceptNode(aPreviousNode);        if (accepted) {            // if accepted, update the current node, and return it.            fCurrentNode = aPreviousNode;            return fCurrentNode;        }    }    // there are no nodes?    return 0;}/** The node is accepted if it passes the whatToShow and the filter. */bool DOMNodeIteratorImpl::acceptNode (DOMNode* node) {	if (fDetached)		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);    if (fNodeFilter == 0) {        return ((fWhatToShow & (1 << (node->getNodeType() - 1))) != 0);    } else {        return ((fWhatToShow & (1 << (node->getNodeType() - 1))) != 0)            && fNodeFilter->acceptNode(node) == DOMNodeFilter::FILTER_ACCEPT;    }}/** Return node, if matches or any parent if matches. */DOMNode* DOMNodeIteratorImpl::matchNodeOrParent (DOMNode* node) {    for (DOMNode* n = fCurrentNode; n != fRoot; n = n->getParentNode()) {        if (node == n) return n;    }    return 0;}/** The method nextNode(DOMNode, bool) returns the next node *  from the actual DOM tree. * *  The bool visitChildren determines whether to visit the children. *  The result is the nextNode. */DOMNode* DOMNodeIteratorImpl::nextNode (DOMNode* node, bool visitChildren) {	if (fDetached)		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);    if (!node) return fRoot;    DOMNode* result = 0;    // only check children if we visit children.    if (visitChildren) {        //if hasChildren, return 1st child.        if (node->hasChildNodes()) {            result = node->getFirstChild();            return result;        }    }    // if hasSibling, return sibling    if (node != fRoot) {        result = node->getNextSibling();        if (result != 0) return result;        // return parent's 1st sibling.        DOMNode* parent = node->getParentNode();        while ((parent != 0) && parent != fRoot) {            result = parent->getNextSibling();            if (result != 0) {                return result;            } else {                parent = parent->getParentNode();            }        } // while (parent != 0 && parent != fRoot) {    }    // end of list, return 0    return 0;}/** The method previousNode(DOMNode) returns the previous node *  from the actual DOM tree. */DOMNode* DOMNodeIteratorImpl::previousNode (DOMNode* node) {	if (fDetached)		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);    DOMNode* result = 0;    // if we're at the root, return 0.    if (node == fRoot)			return 0;    // get sibling    result = node->getPreviousSibling();    if (!result) {        //if 1st sibling, return parent        result = node->getParentNode();        return result;    }    // if sibling has children, keep getting last child of child.    if (result->hasChildNodes()) {        while (result->hasChildNodes()) {            result = result->getLastChild();        }    }    return result;}/** Fix-up the iterator on a remove. Called by DOM or otherwise, *  before an actual DOM remove. */void DOMNodeIteratorImpl::removeNode (DOMNode* node) {	if (fDetached)		throw DOMException(DOMException::INVALID_STATE_ERR, 0, GetDOMNodeIteratorMemoryManager);    // Implementation note: Fix-up means setting the current node properly    // after a remove.    if (!node) return;    DOMNode* deleted = matchNodeOrParent(node);    if (!deleted) return;    if (fForward) {        fCurrentNode = previousNode(deleted);    } else    // if (!fForward)    {        DOMNode* next = nextNode(deleted, false);        if (next != 0) {            // normal case: there _are_ nodes following this in the iterator.            fCurrentNode = next;        } else {            // the last node in the iterator is to be removed,            // so we set the current node to be the previous one.            fCurrentNode = previousNode(deleted);            fForward = true;        }    }}void DOMNodeIteratorImpl::release(){    detach();    // for performance reason, do not recycle pointer    // chance that this is allocated again and again is not usual}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

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