

#include <stdio.h>
#include "expat.h"

#define BUFFSIZE  8192

char Buff[BUFFSIZE];

int Depth;

// Displaying the beginning of the element

static void XMLCALL start(void *data, const char *name, const char **attr)
{
  int i;

  for (i = 0; i < Depth; i++)   printf("  ");

  printf("<%s", name);

  for (i = 0; attr[i]; i += 2)
  {
    printf(" %s='%s'", attr[i], attr[i + 1]);
  }

  printf(" >\n");
  Depth++;
}

// Displaying the end of the element

static void XMLCALL end(void *data, const char *name)
{
  int i;
  Depth--;
  for (i = 0; i < Depth; i++)   printf("  ");
  printf("</%s>\n", name);
}

// Test if a real content, this tools handle any char outside elements!

bool valid(const char *str, int len)
{
  int i;
  char c;

  for(i = 0; i < len; i++)
  {
    c = str[i];
    if(c == 13) continue;
    if(c == 10) continue;
    if(c == ' ') continue;
    return true;
  }
  return false;
}




// Displaying the content

static void XMLCALL content(void *data, const char *thetext, int len)
{
  int i;

  if(!valid(thetext, len)) return;

  for (i = 1; i < Depth; i++)  printf("  ");
  for(i = 0; i < len; i++)
   {
     putchar(thetext[i]);
   }
  printf("\n");
}


int main(int argc, char *argv[])
{
  const char *fname;
  FILE *fp;

  if(argc < 2)
  {
    puts("Syntax: display file.xml");
    exit(0);
  }

  fname = argv[1];

  //printf("reading... %s\n", fname);

  XML_Parser p = XML_ParserCreate(NULL);
  if (! p) {
    fprintf(stderr, "Couldn't allocate memory for parser\n");
    exit(-1);
  }

  XML_SetElementHandler(p, start, end);
  XML_SetCharacterDataHandler(p, content);

  fp = fopen(fname, "r");

  for (;;)
  {
    int done;
    int len;

    len = fread(Buff, 1, BUFFSIZE, fp);
    if (ferror(fp))
    {
      fprintf(stderr, "Read error\n");
      exit(-1);
    }
    done = feof(fp);

    if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR)
    {
      fprintf(stderr, "Parse error at line %d:\n%s\n",
              XML_GetCurrentLineNumber(p),
              XML_ErrorString(XML_GetErrorCode(p)));
      exit(-1);
    }

    if(done) break;
  }
  return 0;
}
