?? domnodeiteratorimpl.cpp
字號:
/* * 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 + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -