[Expat-discuss] Strange problem Parsing
Sashidhar Reddy
msreddy999 at rediffmail.com
Fri Jul 16 21:57:15 CEST 2004
Hi ,
I am trying to parse a simple XML file using expat in C++. I cant parse correctly. There are cases when it worked correctly and cases when it doesnt. I am posting a stripped down version of my code along with the corresponding xml file. This never seem to work and I cant see anything wrong with it :(. Any help is highly appreciated. Thanks.
/*
----Header File----
Parms.h
*/
#define PARMS_H
#include <vector>
#include <string>
using namespace std;
const int BUFFER_SIZE=8192;
const int UN_INITIALISED = -999;
class scenario{
friend class Parms;
private:
int id;
public:
scenario() : id(UN_INITIALISED){ };
void print()
{
cerr<<"\tId: "<<id<<endl;
}
};
class Parms{
private:
bool initialized;
int currIndex;
string currTag;
vector<scenario> scenarios;
/** Parsing functions. */
static void dataHandler(void *userData,const char *name,int len);
void xmlDataHandler(const char *name, int len);
static void startElement(void *userData,const char *name,const char **atts);
void startXmlElement(const char *name, const char **atts);
static void endElement(void *userData,const char *name);
void endXmlElement(const char *name);
public:
Parms();
~Parms();
int read_parms(const string& fname);
void print();
};
/* Parms.cpp file */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <expat.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <vector>
#include <iostream>
// #include <Units.h>
#include "Parms.h"
using namespace std;
Parms::Parms()
{
scenarios.clear();
initialized = false;
}
Parms::~Parms()
{
scenarios.clear();
}
void Parms::print()
{
if(!initialized){
cerr<<"Not initialized"<<endl;
return;
}
cerr<<"\n------------------Tracking Pameters------------------\n";
vector<scenario>::iterator titerator;
for(titerator = scenarios.begin(); titerator != scenarios.end(); titerator++)
titerator->print();
cerr<<"--------------------------------------------------------\n";
}
/********PARSING FUNCTIONS*************/
void Parms::startElement(void *userData, const char *name, const char **atts)
{
Parms *tParms = (Parms *)userData;
tParms->startXmlElement(name,atts);
}
void Parms::startXmlElement(const char *name, const char **atts)
{
cerr<<"Start Element "<<name<<endl;
if(strcmp(name,"Parms")==0)
scenarios.clear();
else if(strcmp(name,"scenario")==0 && atts[1][0]!='\0'){
scenario *currScenario = new scenario();
scenarios.push_back(*currScenario);
currIndex = scenarios.size()-1;
}
currTag.erase();
currTag = string(name);
}
void Parms::endElement(void *userData, const char *name)
{
cerr<<"End of Element "<<name<<endl;
}
void Parms::dataHandler(void *userData, const char *name, int len)
{
Parms *trackerParms = (Parms *)userData;
trackerParms->xmlDataHandler(name,len);
}
void Parms::xmlDataHandler(const char *name, int len)
{
cerr<<"Data Handler for "<<currTag<<endl;
char temp[512];
bool blank;
int num_args, i1, i2;
// test to see if this is a blank line
for(int i=0, blank=true; (i<len) && (blank==true); i++)
{
if(name[i] == 0)
break;
if(! isspace(name[i]))
blank=false;
}
// if it is, we don't do anything
if(blank)
return;
// now, copy name into a local string, with the right length
strncpy(temp,name,len);
temp[len]='\0';
cerr<<"Value for tag "<<currTag<<" is "<<temp<<endl;
if(currTag == "scenario_id")
scenarios[currIndex].id = (atoi(temp));
else
cerr<<"Unknown tag "<<currTag<<". Ignoring"<<endl;
}
int Parms::read_parms(const string& fname)
{
FILE *fp;
char buf[BUFFER_SIZE];
int done;
XML_Parser parser;
bool parse_error=false;
if(fname.empty()){
cerr<<"Parms::read_parms(): No filename provided\n";
return -1;
}
// open the input file
fp=fopen(fname.c_str(),"r");
if(fp==NULL){
cerr<<"Parms::read_parms(): Can not open file "<<fname<<endl;
return -1;
}
// set up the expat parser
parser=XML_ParserCreate(NULL);
XML_SetUserData(parser,this);
XML_SetElementHandler(parser,startElement,endElement);
XML_SetCharacterDataHandler(parser,dataHandler);
do {
size_t len = fread(buf, 1, sizeof(buf), fp);
done = len < sizeof(buf);
if (!XML_Parse(parser, buf, len, done)) {
fprintf(stderr,
"%s at line %d\n",
XML_ErrorString(XML_GetErrorCode(parser)),
XML_GetCurrentLineNumber(parser));
parse_error=true;
break;
}
} while (!done);
XML_ParserFree(parser);
fclose(fp);
if(parse_error){
return -1;
}else
initialized = true;
}
int main()
{
string filename = "/home/sam/Parms.xml";
Parms *tParms = new Parms();
tParms->read_parms(filename);
tParms->print();
exit(1);
}
/****** XML File USed ::: Parms.xml****/
<Parms>
<scenario name="unknown">
<scenario_id>0</scenario_id>
</scenario>
<scenario name="abcd">
<scenario_id>1</scenario_id>
</scenario>
<scenario name="efgh">
<scenario_id>2</scenario_id>
</scenario>
<scenario name="ijkl">
<scenario_id>3</scenario_id>
</scenario>
</Parms>
More information about the Expat-discuss
mailing list