nodeiteratorimpl.cpp

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

CPP
395
字号
/* * Copyright 1999-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: NodeIteratorImpl.cpp,v 1.4 2004/09/08 13:55:43 peiyongz Exp $ */// NodeIteratorImpl.cpp: implementation of the NodeIteratorImpl class.////////////////////////////////////////////////////////////////////////#include "NodeIteratorImpl.hpp"#include "DOM_Document.hpp"#include "DOM_DOMException.hpp"#include "DocumentImpl.hpp"XERCES_CPP_NAMESPACE_BEGIN//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////NodeIteratorImpl::NodeIteratorImpl (): fDetached(false),    fNodeFilter(0){}	NodeIteratorImpl::~NodeIteratorImpl (){	fDetached = false;}void NodeIteratorImpl::detach (){	fDetached = true;}NodeIteratorImpl::NodeIteratorImpl (                                    DOM_Node root,                                    unsigned long whatToShow,                                    DOM_NodeFilter* nodeFilter,                                    bool expandEntityRef):   fDetached(false),    fRoot(root),    fCurrentNode(0),    fWhatToShow(whatToShow),    fNodeFilter(nodeFilter),    fForward(true),    fExpandEntityReferences(expandEntityRef){	}NodeIteratorImpl::NodeIteratorImpl ( const NodeIteratorImpl& toCopy)    :   fDetached(toCopy.fDetached),    fRoot(toCopy.fRoot),    fCurrentNode(toCopy.fCurrentNode),    fWhatToShow(toCopy.fWhatToShow),    fNodeFilter(toCopy.fNodeFilter),    fForward(toCopy.fForward),    fExpandEntityReferences(toCopy.fExpandEntityReferences){}NodeIteratorImpl& NodeIteratorImpl::operator= (const NodeIteratorImpl& other) {    fRoot                   = other.fRoot;    fCurrentNode            = other.fRoot;    fWhatToShow             = other.fWhatToShow;    fNodeFilter             = other.fNodeFilter;    fForward                = other.fForward;	fDetached               = other.fDetached;    fExpandEntityReferences = other.fExpandEntityReferences;    return *this;}/** Return the Root Node. */DOM_Node NodeIteratorImpl::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 NodeIteratorImpl::getWhatToShow () {    return fWhatToShow;}/** Return the filter */DOM_NodeFilter* NodeIteratorImpl::getFilter () {    return fNodeFilter;}/** Get the expandEntity reference flag. */bool NodeIteratorImpl::getExpandEntityReferences(){    return fExpandEntityReferences;}/** Return the next DOM_Node in the Iterator. The node is the next node in *  depth-first order which also passes the filter, and whatToShow. *  A null return means either that */DOM_Node NodeIteratorImpl::nextNode () {	if (fDetached)		throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null);	DOM_Node result;    // if root is null there is no next node.    if (fRoot.isNull())			return result;    DOM_Node 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.isNull()) {            //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 null check?        // nothing in the list. return null.        if (aNextNode.isNull())					return result;        // 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 result;}/** 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. */DOM_Node NodeIteratorImpl::previousNode () {	if (fDetached)		throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null);			DOM_Node result;    // if the root is null, or the current node is null, return null.    if (fRoot.isNull() || fCurrentNode.isNull())			return result;    DOM_Node aPreviousNode = fCurrentNode;    bool accepted = false;    while (!accepted) {        if (fForward && ! aPreviousNode.isNull()) {            //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 null, we're at head or past the root,        // so return null.        if (aPreviousNode.isNull())					return result;        // 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 result;}/** The node is accepted if it passes the whatToShow and the filter. */bool NodeIteratorImpl::acceptNode (DOM_Node node) {	if (fDetached)		throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null);    if (fNodeFilter == 0) {        return ((fWhatToShow & (1 << (node.getNodeType() - 1))) != 0);    } else {        return ((fWhatToShow & (1 << (node.getNodeType() - 1))) != 0)            && fNodeFilter->acceptNode(node) == DOM_NodeFilter::FILTER_ACCEPT;    }}/** Return node, if matches or any parent if matches. */DOM_Node NodeIteratorImpl::matchNodeOrParent (DOM_Node node) {		DOM_Node result;    for (DOM_Node n = fCurrentNode; n != fRoot; n = n.getParentNode()) {        if (node == n) return n;    }    return result;}/** The method nextNode(DOM_Node, bool) returns the next node *  from the actual DOM tree. * *  The bool visitChildren determines whether to visit the children. *  The result is the nextNode. */DOM_Node NodeIteratorImpl::nextNode (DOM_Node node, bool visitChildren) {	if (fDetached)		throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null);    if (node.isNull()) return fRoot;    DOM_Node result;    // 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.isNull()) return result;        // return parent's 1st sibling.        DOM_Node parent = node.getParentNode();        while (!parent.isNull() && parent != fRoot) {            result = parent.getNextSibling();            if (!result.isNull()) {                return result;            } else {                parent = parent.getParentNode();            }        } // while (parent != null && parent != fRoot) {    }    // end of list, return null    DOM_Node aNull;    return aNull;}/** The method previousNode(DOM_Node) returns the previous node *  from the actual DOM tree. */DOM_Node NodeIteratorImpl::previousNode (DOM_Node node) {	if (fDetached)		throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null);    DOM_Node result;    // if we're at the root, return null.    if (node == fRoot)			return result;    // get sibling    result = node.getPreviousSibling();    if (result.isNull()) {        //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 NodeIteratorImpl::removeNode (DOM_Node node) {	if (fDetached)		throw DOM_DOMException(DOM_DOMException::INVALID_STATE_ERR, null);    // Implementation note: Fix-up means setting the current node properly    // after a remove.    if (node.isNull())				return;    DOM_Node deleted = matchNodeOrParent(node);    if (deleted.isNull()) return;    if (fForward) {        fCurrentNode = previousNode(deleted);    } else    // if (!fForward)    {        DOM_Node next = nextNode(deleted, false);        if (! next.isNull()) {            // 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 NodeIteratorImpl::unreferenced(){    DOM_Document doc = fRoot.getOwnerDocument();    DocumentImpl* impl;    if (! doc.isNull()) {        impl = (DocumentImpl *) doc.fImpl;    }    else        impl = (DocumentImpl *) fRoot.fImpl;    if (impl->iterators != 0L) {        int i;        int sz = impl->iterators->size();        for (i = 0; i < sz; i++)            if (impl->iterators->elementAt(i) == this) {                impl->iterators->removeElementAt(i);                break;            }    }//    delete this;    NodeIteratorImpl* ptr = this;    delete ptr;}XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

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