In C++
Write a program that handles IO of Employee objects containing the following data attributes: name (string) id (int) address (string) city (string) state (string) country (string) phone (string) salary (double) You will read XML representations of Employee objects from a file, and then will create a file of fixed-length records of Employee data. Do not use an XML software library or regular expressions for this assigament, just use operations from the std::string class for parsing input (see the Notes section below). The input files have no XML beader tag The XML tags are named the same as the attributes (ignoring case, of course). For those that know XML, don't worry about top-level, system XML tags; we just want sequences of same level Employee tag groups with attributes tags nested to one level only, like the following indented to show the nesting, but they may appear free- form in the file; don't assume that there will be any newlines or fonnatting):
12345 John Doe 40000 ) for these cases. You will catch these exceptions in your main function. Your Employee class must contain at least the following void display (std::ostream& const: 17 Write a readable Employee representation to a stream void write(std::ostreank) const: 1/ Write a fixed-length record to current file position void store (std::iostream) const: 1/ Overwrite for append) record in (to) file void toXML<:ostream const: write xml record for employee static read from current file position retrieve int search by id fronxml the a stream do not change any signatures or return types. define constructors you feel needful. need destructor as objects only contain string and numbers. fromxml rerum nullptr if they end of also returns requested is found in file. throw exceptions data errors. following an overview what your main function should to test functions using employee.xml this zip obtain name command line print error message halt program there no comunand-line argument provided does exist. each repeatedly calling which creates object on-tine-fly store it vector recommend unique_pts loop through cout display member next step create new fixed-length records. explained below. records order appear vector. open fstream with both capability binary format. clear preparation step. traverse repeated calls tead filling newly emptied pointers read. representation retrieve. salary retrieved modified back employee::store again its verify that now has updated salary. own unique along other information. employee: store. cout. make sure don leak memory here sample output steps .la.out id: hane: john doe address: w. treeline dr. city: tucson state: arizona country: usa phone: salary: name: jane jack dough princeton dearborn michigan> John Doe 1234 2238 W. Treeline Dr. Tucson State>Arizona USA 528-742-244848000 Jane Doe 4321 60000 Jack Dough/Name> 12345 24437 Princeton Dearborn Michigan USA 383-427-6153148800 Found: id: 12345 name: Jack Dough address: 24437 Princeton city: Dearborn state: Michigan country: USA phone: 383-427-0153 salary: 140000 150686 Note that store and retrieve search the file for the correct record by looking at the ids in each record retrieve fails if no record with the requested id is found; return a nulptr in that case store overwrites the record if it exists already; otherwise it appends a new record to the file. Throw runtime_error exceptions with a suitable message if any required XML tags are missing or if any end tags for existing start tags are missing, or for any other abnormalities. Notes Your XML input function should not depend on the line orientation of the input stream, so don't read text a line at a time (i.e., don't use getline() with the newline character as its delimiter (other delimiters are okay]the input should be free form", like source code is to a compiler). Do not use any third-party XML libraries. I want you to do your own basic, custom parsing by using simple string operations. An important part of this assignment is also the proper use of exceptions. To process fixed-length records in a file requires special processing. Ow Employee objects use std::string objects, which are allowed to have strings of any length, but we need to write fixed-length, byte-records to files using ostream:.write and we read them back into memory with istream: read). Some strings may therefore get truncated. Here is the record structure I used for transferring Employee data to and from files. struct EmployeeRec int id: char name :311: char address [261: char city1211 char state:2110 char country[211 char phone211: double salary: 3: Note that the strings here are C-style, zero-delimited strings. You need to copy data from and to an EmployeeRec when doing 10 with the binary file. It is the Employee Rec object that is actually written/read. See employeedb.cpp You may find some of the following functions useful for this assignment: istream::gcount, istream: : seekg. istream: tellg, istream read, ostream::write. istream::getline (istrean&, string&. char). istream:unget. ios::clear. string: Ecopy. string: :empty. stringstoi, string stof, string find_first_not_of, string find, string:: substr. string clear, string.c_str. The goal here is to understand strings and streams better, as well as serializing simple object data. Along the way, I ended up creating a few bandy XML-related functions for future use, which I named getNextTag, getNextValue, both of which take an input stream as a parameter. You might find such a practice useful. Remember to do a case- insensitre compare when looking for tag names. For case-insensitive string comparisons, it is handy to use the non- standard C function, strcasecmp, defined in Sample input files are in this zip file. The files employee?.xml through employees.xml have errors that you should catch through exceptions and print a meaningful message. Here's my output: Slaout employee2.xml Missing tag S.a.out employee4.xml Invalid tag: Employee 5./a.out employees.xml Missing tags 5./a.out employee7.xml Invalid tag: village 5./a.out employees.xml Missing 12345 John Doe 40000 ) for these cases. You will catch these exceptions in your main function. Your Employee class must contain at least the following void display (std::ostream& const: 17 Write a readable Employee representation to a stream void write(std::ostreank) const: 1/ Write a fixed-length record to current file position void store (std::iostream) const: 1/ Overwrite for append) record in (to) file void toXML<:ostream const: write xml record for employee static read from current file position retrieve int search by id fronxml the a stream do not change any signatures or return types. define constructors you feel needful. need destructor as objects only contain string and numbers. fromxml rerum nullptr if they end of also returns requested is found in file. throw exceptions data errors. following an overview what your main function should to test functions using employee.xml this zip obtain name command line print error message halt program there no comunand-line argument provided does exist. each repeatedly calling which creates object on-tine-fly store it vector recommend unique_pts loop through cout display member next step create new fixed-length records. explained below. records order appear vector. open fstream with both capability binary format. clear preparation step. traverse repeated calls tead filling newly emptied pointers read. representation retrieve. salary retrieved modified back employee::store again its verify that now has updated salary. own unique along other information. employee: store. cout. make sure don leak memory here sample output steps .la.out id: hane: john doe address: w. treeline dr. city: tucson state: arizona country: usa phone: salary: name: jane jack dough princeton dearborn michigan> John Doe 1234 2238 W. Treeline Dr. Tucson State>Arizona USA 528-742-244848000 Jane Doe 4321 60000 Jack Dough/Name> 12345 24437 Princeton Dearborn Michigan USA 383-427-6153148800 Found: id: 12345 name: Jack Dough address: 24437 Princeton city: Dearborn state: Michigan country: USA phone: 383-427-0153 salary: 140000 150686 Note that store and retrieve search the file for the correct record by looking at the ids in each record retrieve fails if no record with the requested id is found; return a nulptr in that case store overwrites the record if it exists already; otherwise it appends a new record to the file. Throw runtime_error exceptions with a suitable message if any required XML tags are missing or if any end tags for existing start tags are missing, or for any other abnormalities. Notes Your XML input function should not depend on the line orientation of the input stream, so don't read text a line at a time (i.e., don't use getline() with the newline character as its delimiter (other delimiters are okay]the input should be free form", like source code is to a compiler). Do not use any third-party XML libraries. I want you to do your own basic, custom parsing by using simple string operations. An important part of this assignment is also the proper use of exceptions. To process fixed-length records in a file requires special processing. Ow Employee objects use std::string objects, which are allowed to have strings of any length, but we need to write fixed-length, byte-records to files using ostream:.write and we read them back into memory with istream: read). Some strings may therefore get truncated. Here is the record structure I used for transferring Employee data to and from files. struct EmployeeRec int id: char name :311: char address [261: char city1211 char state:2110 char country[211 char phone211: double salary: 3: Note that the strings here are C-style, zero-delimited strings. You need to copy data from and to an EmployeeRec when doing 10 with the binary file. It is the Employee Rec object that is actually written/read. See employeedb.cpp You may find some of the following functions useful for this assignment: istream::gcount, istream: : seekg. istream: tellg, istream read, ostream::write. istream::getline (istrean&, string&. char). istream:unget. ios::clear. string: Ecopy. string: :empty. stringstoi, string stof, string find_first_not_of, string find, string:: substr. string clear, string.c_str. The goal here is to understand strings and streams better, as well as serializing simple object data. Along the way, I ended up creating a few bandy XML-related functions for future use, which I named getNextTag, getNextValue, both of which take an input stream as a parameter. You might find such a practice useful. Remember to do a case- insensitre compare when looking for tag names. For case-insensitive string comparisons, it is handy to use the non- standard C function, strcasecmp, defined in Sample input files are in this zip file. The files employee?.xml through employees.xml have errors that you should catch through exceptions and print a meaningful message. Here's my output: Slaout employee2.xml Missing tag S.a.out employee4.xml Invalid tag: Employee 5./a.out employees.xml Missing tags 5./a.out employee7.xml Invalid tag: village 5./a.out employees.xml Missing