#include #include "ExpatInterface/Element.h" #include "xmlToolFinder.hh" namespace xmlTool { const xml::Element & Finder::findUnderTheUniqueElement ( const xml::Element & elt, const std::string & tag, const std::string & attType, const std::string & attValue) { int numberOfMatches = countUnderElementsMatching(elt, tag, attType, attValue); // Check that query specified a unique element. if (numberOfMatches != 1) { cerr << "ERROR: In findUnderTheUniqueElement there were " << numberOfMatches << " of the following:" << endl << " tag: " << tag << endl << " attType: " << attType << endl << "attValue: " << attValue << endl << "There should be exactly one." << endl; } assert(numberOfMatches == 1); // Good. The last call has therefore set _lastMatch // exactly once, and we can return it. return *(this->_lastMatch); }; int Finder::countUnderElementsMatching(const xml::Element & elt, const std::string & tag, const std::string & attType, const std::string & attValue) { // It is meaningless to search for a non blank attValue if attType // is blank, so we can assert the following: assert(!(attType==string("") && attValue!=string(""))); int numberFoundSoFar = 0; xml::Element::ElementCollection::const_iterator it; for (it = elt.getChildren().begin(); it != elt.getChildren().end(); it++) { // We could look at the element **it for a match right away, // but I'm going to do that later. First I'll have a look // at it's children: numberFoundSoFar += this->countUnderElementsMatching(**it, tag, attType, attValue); // OK. Now I'll look at **it itself. if ( (tag == (*it)->getTagName()) || tag == string("") ) { // OK, we're sitting on an element which matches our tag. // (or we're not searching for tags!) // For the moment (see later), we will have to ban searching // for attribute types without tags: assert(!( tag==string("") && attType!=string("") )); // So, do we need to check the attribute? if (attType!=string("")) { // Yes, we do need to check the attribute. // We will this assume that attType is a valid attribute // to dereference here. We cannot check this, though, // until xml::Element::getAttributes() is fixed. string thisAttValue=(**it)[attType]; if (thisAttValue == attValue) { // The tag and values match! // Make a note of this element ... this->_lastMatch=(*it); // ... and increment number of found elements. numberFoundSoFar++; } } else { // No, we do not need to check the attribute. this->_lastMatch=(*it); numberFoundSoFar++; } } } // Let's return our answer. return numberFoundSoFar; } // end of Finder::countUnderElementsMatching } // end of xmlTool namespace