///////////////////////////////////////////////////////////////// // xmlParser.cpp - prototype demonstration program // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2002 // ///////////////////////////////////////////////////////////////// /* Note: - This demonstration uses a tokenizer to look for XML elements. You may find it just as easy, and simpler to directly scan the XML string, read from file. - This prototype has no error handling. - xmlParser IS NOT A MODULE. It is simply a brief prototype, that is, a demonstration of a design strategy. To become a Module it needs a header file, manual page, maintenance page, and appropriate preprocessor guard statements. See the tok module code (part of this project) as an example. */ #include #include #include "tok.h" using namespace std; /////////////////////////////////////////////////////////////// // xmlParse class declaration class xmlParse { public: xmlParse(istream &in); bool getElem(const std::string &parent = ""); bool nextElem(); void indent(); private: token toker; int indentSize; }; //----< constructor >------------------------------------------ inline xmlParse::xmlParse(istream &in) : toker(in), indentSize(0) { }; //----< send spaces to output to indent display line >--------- void xmlParse::indent() { for(int i=0; i------ // // Notes: // - getElem assumes opening '<' has been collected by caller. // - This version simply announces the elements it finds, but // does not build an in-memory representation, e.g., parse tree. // - This version ignores attributes in opening tag and ignores // the body unless it contains child elements. You will want // to address these issues in your project #1 // bool xmlParse::getElem(const std::string &parent) { const int indentDelta = 3; // change of indentSize // get element name and display it std::string tok, name; if(toker.getTok(tok)) { name = tok; cout << "\n "; indent(); cout << "element " << name; } if(parent.size() > 0) cout << ", child of " << parent; else cout << ", root element"; // ignoring attributes look for child elements or end while(toker.getTok(tok)) { if(tok == "\n") continue; if(tok == string("<")) { indentSize += indentDelta; getElem(name); } do { if(tok == ">") break; cout << ", attribute name = " << tok; toker.getTok(tok); tok.erase(tok.begin()); cout << ", value = " << tok; } while(toker.getTok(tok)); continue; if(tok == string("' indentSize -= indentDelta; return toker.good(); } } return false; } //----< find start of next element >--------------------------- // // skips over opening banner and comments // bool xmlParse::nextElem() { std::string tok; while(toker.getTok(tok)) if(tok == string("<")) return true; return false; } // //----< test stub >-------------------------------------------- void main(int argc, char *argv[]) { if(argc==1) { cout << "\n Please enter name of XML file to parse\n\n"; return; } ifstream in; for(int i=1; i