[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