XmlTree::ConstIter::ConstIter( const XmlTree &root, const string &filterPath, bool caseSensitive, char separator ) : mCaseSensitive( caseSensitive ) { mFilter = split( filterPath, separator ); // we ignore a leading separator so that "/one/two" is equivalent to "one/two" if( ( ! filterPath.empty() ) && ( filterPath[0] == separator ) && ( ! mFilter.empty() ) ) mFilter.erase( mFilter.begin() ); if( mFilter.empty() ) { // empty filter means nothing matches setToEnd( &root.getChildren() ); return; } for( vector<string>::const_iterator filterComp = mFilter.begin(); filterComp != mFilter.end(); ++filterComp ) { if( mIterStack.empty() ) // first item mSequenceStack.push_back( &root.getChildren() ); else mSequenceStack.push_back( &(*mIterStack.back())->getChildren() ); Container::const_iterator child = findNextChildNamed( *mSequenceStack.back(), mSequenceStack.back()->begin(), *filterComp, mCaseSensitive ); if( child != (mSequenceStack.back())->end() ) mIterStack.push_back( child ); else { // failed to find an item that matches this part of the filter; mark as finished and return setToEnd( &root.getChildren() ); return; } } }
XmlTree* XmlTree::getNodePtr( const string &relativePath, bool caseSensitive, char separator ) const { XmlTree *curNode = const_cast<XmlTree*>( this ); vector<string> pathComponents = split( relativePath, separator ); for( vector<string>::const_iterator pathIt = pathComponents.begin(); pathIt != pathComponents.end(); ++pathIt ) { if( pathIt->empty() ) continue; Container::const_iterator node = XmlTree::findNextChildNamed( curNode->getChildren(), curNode->getChildren().begin(), *pathIt, caseSensitive ) ; if( node != curNode->getChildren().end() ) curNode = const_cast<XmlTree*>( node->get() ); else return 0; } return curNode; }