Here is the full code for the header and class file from the xml reader project
Here is the cppxmlreader.h file.
#ifndef CPPXMLREADER_H #define CPPXMLREADER_H #include <string> #include <vector> // using the namespace std for the string type, vector using namespace std; const int CHARACTERLENGHT = 80; const string BADXMLVERSION = "Xml version - first line ? - problem"; const string BADTAGNAME = "Tag name was not present"; const string BADXMLTAGEND = "End tag is not the same as tag name"; const string BADATTRIBUTE = "Attribute in wrong format attributeName=\"attributeValue\""; struct xmlAttribute { string _attributeName, _attributeValue; }; class xmlObject { private : string _tagName, _tagValue; vector<xmlAttribute> _attributes; bool _xmlMainDetails; public: xmlObject() { _xmlMainDetails = false;} ; xmlObject(string tag, string tValue, xmlAttribute attribute); void setTagName(string tagName); void setTagValue(string tagValue); void addAttributes(xmlAttribute attribute); void setAttributeVector(vector<xmlAttribute> setAtt); void setXmlMainDetails(bool value); bool getXmlMainDetails(); void printOutXmlObject(); }; class xmlReader { protected: vector<xmlObject> _xmlMainDetails; vector<xmlObject> _xmlDetails; public: xmlReader(); // open file and read in the xml file and place into the _xmlDetails bool loadFile(string filename); void printOuterXML(); private : xmlObject readLine(string xmlToSplitUp, string* tagName); string readUntilCharacter(string line, char characterStart, char characterEnd, string *returnLine); xmlAttribute getAttribute(string attributeString); vector<xmlAttribute> getAttributesFromString(string str); }; #endif // CPPXMLREADER_H |
Here is the cppxmlreader.cpp file
#include "cppxmlreader.h" #include <iostream> #include <string.h> #include <fstream> using namespace std; /* xmlObject */ // constructor for xmlObject, if any details are passed whilst constructing xmlObject::xmlObject(string tag, string tValue, xmlAttribute attribute) { _tagName = tag; _tagValue = tValue; _attributes.push_back(attribute); } // xml <tagname attributes="attributesvalue">VALUE</tagname> // set the tag name void xmlObject::setTagName(string tagName) { _tagName = tagName; } // set tag value void xmlObject::setTagValue(string tagValue) { _tagValue = tagValue; } // add attributes to the vector attributes variable void xmlObject::addAttributes(xmlAttribute attribute) { _attributes.push_back(attribute); } // fill in the vector attributes variable. void xmlObject::setAttributeVector(vector<xmlAttribute> setAtt) { _attributes = setAtt; } // print out the xml object detais, with the attributes values. void xmlObject::printOutXmlObject() { cout << "XML Object" << endl; cout << "Tagname :" << _tagName << endl; cout << "Tagvalue :" << _tagValue << endl; for (int i= 0; i < (int)_attributes.size(); i++) { cout << "Attribute " << i << " : Name : "<< _attributes.at(i)._attributeName << " Value : " << _attributes.at(i)._attributeValue << endl; } } // set the main set details value void xmlObject::setXmlMainDetails(bool value) { _xmlMainDetails = value; } // get a boolean value to see if the xmlObject is the main <?xml .. ?> value bool xmlObject::getXmlMainDetails() { return _xmlMainDetails; } /*xmlReader*/ xmlReader::xmlReader() { } // attribute is normally in the format of attributeName="attributeValue" xmlAttribute xmlReader::getAttribute(string attributeString) { xmlAttribute returnAttribute; // make sure that there is a = in the attribute string int findEqual = attributeString.find('='); if (findEqual > 0) { // set the attribute name to the substring till the equal returnAttribute._attributeName = attributeString.substr(0,findEqual); // make sure that there is some characters after the '=' sign. if (attributeString.length() > (findEqual+3)) { returnAttribute._attributeValue = attributeString.substr(findEqual+2,(attributeString.length() - (findEqual +3))); } else throw BADATTRIBUTE; }else // if there does not appear to be ="" at the end of the string then throw a error. throw BADATTRIBUTE; return returnAttribute; } vector<xmlAttribute> xmlReader::getAttributesFromString(string str) { vector<xmlAttribute> returnAtt; xmlAttribute attribute; int args; char st1[CHARACTERLENGHT]; // args normally equals 1 because there is a attribute present // else there was no attribute there, just do one at a time args = sscanf(str.c_str(), "%s", st1); while (args == 1 && (str.length() > 1)) { // see if there is a real attribute attributeName="attributeValue" try { attribute = getAttribute(st1); // push back in the vector array the attribute returnAtt.push_back(attribute); } catch (string errorStr) // any errors { cout << "ERROR : " << errorStr << endl; } // re-do the string to pull out any more attributes. str = str.substr(strlen(st1)); // see if there is any more attributes present. args = sscanf(str.c_str(), "%s", st1); } return returnAtt; } // scan through the xml string and pull out the tags and the attributes and value. xmlObject xmlReader::readLine(string xmlToSplitUp, string* tagName) { xmlObject returnObj; string returnLine, value, endTagName; int findXml; // pick out the tag name, if none then return and throw a bad tag name error. *tagName = readUntilCharacter(xmlToSplitUp, '<','>', &returnLine); if (tagName->length() ==0) { throw BADTAGNAME; return returnObj; } // if there is a xml version etc in the tagname then process the xml version encoding values. findXml=tagName->find("xml"); if ((findXml > 0 && findXml < tagName->length()) && tagName->length() > 1 ) { // this is the xml version etc. // there should be ? at each end of the xml version statement string xmlStr = readUntilCharacter(*tagName, '?','?', &returnLine); if (returnLine != "?") { throw BADXMLVERSION; return returnObj; } // go passed the xml characters. returnLine = xmlStr.substr(findXml+3); // read any of the attributes from the string returnObj.setAttributeVector(getAttributesFromString(returnLine)); // I am storing the version and any other xml details, so set the return value to store in the correct place. returnObj.setXmlMainDetails(true); }else if (tagName->length() > 1) { // need to see if there is any attributes int findTagAtts = tagName->find(' '); if (findTagAtts < tagName->length()) { // the attributes are passed the space character in the tagName variable string attributes = tagName->substr(findTagAtts); // store only the tagName in the tagName variable since pulled out the attributes *tagName = tagName->substr(0,findTagAtts); // get the attributes into a vector and store in the return object returnObj.setAttributeVector(getAttributesFromString(attributes)); } if (returnLine.length() > 1) { // pull out the value in the xml line <tagname>VALUE</tagname> value = readUntilCharacter(returnLine,'>','<',&returnLine); returnObj.setTagValue(value); } if (returnLine.length() > 1) { // pick out the end tag name and make sure it is the same as the first one. endTagName = readUntilCharacter(returnLine,'<','>',&returnLine); string compareEndTag = "/"+*tagName; //if the end tag is not the same as the tag name then throw a error. if (endTagName != compareEndTag) { throw BADXMLTAGEND; } } returnObj.setTagName(*tagName); } return returnObj; } // pick out the characters between two character points, and also return the rest of the line. string xmlReader::readUntilCharacter(string line, char characterStart, char characterEnd, string *returnLine) { string returnString; // find the first occurrence of the character integer placement int firstChar = line.find(characterStart); // if there is one. if (firstChar >= 0) { // setup the return string, even if a second part cannot be found. returnString = line.substr(firstChar+1, (line.length()- firstChar)-1); int secChar = returnString.find(characterEnd); //if the secound part can be found if (secChar > 0) { *returnLine = returnString.substr(secChar, (returnString.length() - secChar)); returnString = returnString.substr(0,secChar); } } return returnString; } // read in the XML file and place each line into the vector xmlObject bool xmlReader::loadFile(string filename) { xmlObject xmlObj; string line, tagName; ifstream xmlfile(filename.c_str()); if (xmlfile.is_open()) { // if the xml version and also the encodingvalues are present. //getline(xmlfile,line); while (!xmlfile.eof()) { // pull out the start tag and compare against the endtag getline(xmlfile,line); try { // pick out the xml details from line and return a xmlObject // to add to the vector array of xml objects // also return the tagName if any futher processing is required. xmlObj = readLine(line, &tagName); // if there is ?xml version etc details present store, else store into the main xml details if (xmlObj.getXmlMainDetails()) { _xmlMainDetails.push_back(xmlObj); } else { _xmlDetails.push_back(xmlObj); } } // if any error occur during the reading of the xml line. catch (string errorStr) { cout << "ERROR : " << errorStr << endl; } } xmlfile.close(); } else { cout << "Unable to open the file" << endl; } } /* print Out the outer XML values */ void xmlReader::printOuterXML() { cout << "XML Reader Main Object (Xml main details) " << endl; for (int i =0; i < _xmlMainDetails.size(); i++) _xmlMainDetails.at(i).printOutXmlObject(); cout << "XML Reader xml details" << endl; for (int i =0; i < _xmlDetails.size(); i++) _xmlDetails.at(i).printOutXmlObject(); } |