(root)/
libxml2-2.12.3/
example/
gjobread.c
       1  /*
       2   * gjobread.c : a small test program for gnome jobs XML format
       3   *
       4   * See Copyright for the status of this software.
       5   *
       6   * Daniel.Veillard@w3.org
       7   */
       8  
       9  #include <stdio.h>
      10  #include <string.h>
      11  #include <stdlib.h>
      12  
      13  /*
      14   * This example should compile and run indifferently with libxml-1.8.8 +
      15   * and libxml2-2.1.0 +
      16   * Check the COMPAT comments below
      17   */
      18  
      19  /*
      20   * COMPAT using xml-config --cflags to get the include path this will
      21   * work with both 
      22   */
      23  #include <libxml/xmlmemory.h>
      24  #include <libxml/parser.h>
      25  
      26  #define DEBUG(x) printf(x)
      27  
      28  /*
      29   * A person record
      30   * an xmlChar * is really an UTF8 encoded char string (0 terminated)
      31   */
      32  typedef struct person {
      33      xmlChar *name;
      34      xmlChar *email;
      35      xmlChar *company;
      36      xmlChar *organisation;
      37      xmlChar *smail;
      38      xmlChar *webPage;
      39      xmlChar *phone;
      40  } person, *personPtr;
      41  
      42  /*
      43   * And the code needed to parse it
      44   */
      45  static personPtr
      46  parsePerson(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
      47      personPtr ret = NULL;
      48  
      49  DEBUG("parsePerson\n");
      50      /*
      51       * allocate the struct
      52       */
      53      ret = (personPtr) malloc(sizeof(person));
      54      if (ret == NULL) {
      55          fprintf(stderr,"out of memory\n");
      56  	return(NULL);
      57      }
      58      memset(ret, 0, sizeof(person));
      59  
      60      /* We don't care what the top level element name is */
      61      /* COMPAT xmlChildrenNode is a macro unifying libxml1 and libxml2 names */
      62      cur = cur->xmlChildrenNode;
      63      while (cur != NULL) {
      64          if ((!xmlStrcmp(cur->name, (const xmlChar *)"Person")) &&
      65  	    (cur->ns == ns))
      66  	    ret->name = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
      67          if ((!xmlStrcmp(cur->name, (const xmlChar *)"Email")) &&
      68  	    (cur->ns == ns))
      69  	    ret->email = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
      70  	cur = cur->next;
      71      }
      72  
      73      return(ret);
      74  }
      75  
      76  /*
      77   * and to print it
      78   */
      79  static void
      80  printPerson(personPtr cur) {
      81      if (cur == NULL) return;
      82      printf("------ Person\n");
      83      if (cur->name) printf("	name: %s\n", cur->name);
      84      if (cur->email) printf("	email: %s\n", cur->email);
      85      if (cur->company) printf("	company: %s\n", cur->company);
      86      if (cur->organisation) printf("	organisation: %s\n", cur->organisation);
      87      if (cur->smail) printf("	smail: %s\n", cur->smail);
      88      if (cur->webPage) printf("	Web: %s\n", cur->webPage);
      89      if (cur->phone) printf("	phone: %s\n", cur->phone);
      90      printf("------\n");
      91  }
      92  
      93  /*
      94   * a Description for a Job
      95   */
      96  typedef struct job {
      97      xmlChar *projectID;
      98      xmlChar *application;
      99      xmlChar *category;
     100      personPtr contact;
     101      int nbDevelopers;
     102      personPtr developers[100]; /* using dynamic alloc is left as an exercise */
     103  } job, *jobPtr;
     104  
     105  /*
     106   * And the code needed to parse it
     107   */
     108  static jobPtr
     109  parseJob(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
     110      jobPtr ret = NULL;
     111  
     112  DEBUG("parseJob\n");
     113      /*
     114       * allocate the struct
     115       */
     116      ret = (jobPtr) malloc(sizeof(job));
     117      if (ret == NULL) {
     118          fprintf(stderr,"out of memory\n");
     119  	return(NULL);
     120      }
     121      memset(ret, 0, sizeof(job));
     122  
     123      /* We don't care what the top level element name is */
     124      cur = cur->xmlChildrenNode;
     125      while (cur != NULL) {
     126          
     127          if ((!xmlStrcmp(cur->name, (const xmlChar *) "Project")) &&
     128  	    (cur->ns == ns)) {
     129  	    ret->projectID = xmlGetProp(cur, (const xmlChar *) "ID");
     130  	    if (ret->projectID == NULL) {
     131  		fprintf(stderr, "Project has no ID\n");
     132  	    }
     133  	}
     134          if ((!xmlStrcmp(cur->name, (const xmlChar *) "Application")) &&
     135              (cur->ns == ns))
     136  	    ret->application = 
     137  		xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
     138          if ((!xmlStrcmp(cur->name, (const xmlChar *) "Category")) &&
     139  	    (cur->ns == ns))
     140  	    ret->category =
     141  		xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
     142          if ((!xmlStrcmp(cur->name, (const xmlChar *) "Contact")) &&
     143  	    (cur->ns == ns))
     144  	    ret->contact = parsePerson(doc, ns, cur);
     145  	cur = cur->next;
     146      }
     147  
     148      return(ret);
     149  }
     150  
     151  /*
     152   * and to print it
     153   */
     154  static void
     155  printJob(jobPtr cur) {
     156      int i;
     157  
     158      if (cur == NULL) return;
     159      printf("=======  Job\n");
     160      if (cur->projectID != NULL) printf("projectID: %s\n", cur->projectID);
     161      if (cur->application != NULL) printf("application: %s\n", cur->application);
     162      if (cur->category != NULL) printf("category: %s\n", cur->category);
     163      if (cur->contact != NULL) printPerson(cur->contact);
     164      printf("%d developers\n", cur->nbDevelopers);
     165  
     166      for (i = 0;i < cur->nbDevelopers;i++) printPerson(cur->developers[i]);
     167      printf("======= \n");
     168  }
     169  
     170  /*
     171   * A pool of Gnome Jobs
     172   */
     173  typedef struct gjob {
     174      int nbJobs;
     175      jobPtr jobs[500]; /* using dynamic alloc is left as an exercise */
     176  } gJob, *gJobPtr;
     177  
     178  
     179  static gJobPtr
     180  parseGjobFile(char *filename ATTRIBUTE_UNUSED) {
     181      xmlDocPtr doc;
     182      gJobPtr ret;
     183      jobPtr curjob;
     184      xmlNsPtr ns;
     185      xmlNodePtr cur;
     186  
     187      /*
     188       * build an XML tree from a the file;
     189       */
     190      doc = xmlReadFile(filename, NULL, XML_PARSE_NOBLANKS);
     191      if (doc == NULL) return(NULL);
     192  
     193      /*
     194       * Check the document is of the right kind
     195       */
     196      
     197      cur = xmlDocGetRootElement(doc);
     198      if (cur == NULL) {
     199          fprintf(stderr,"empty document\n");
     200  	xmlFreeDoc(doc);
     201  	return(NULL);
     202      }
     203      ns = xmlSearchNsByHref(doc, cur,
     204  	    (const xmlChar *) "http://www.gnome.org/some-location");
     205      if (ns == NULL) {
     206          fprintf(stderr,
     207  	        "document of the wrong type, GJob Namespace not found\n");
     208  	xmlFreeDoc(doc);
     209  	return(NULL);
     210      }
     211      if (xmlStrcmp(cur->name, (const xmlChar *) "Helping")) {
     212          fprintf(stderr,"document of the wrong type, root node != Helping");
     213  	xmlFreeDoc(doc);
     214  	return(NULL);
     215      }
     216  
     217      /*
     218       * Allocate the structure to be returned.
     219       */
     220      ret = (gJobPtr) malloc(sizeof(gJob));
     221      if (ret == NULL) {
     222          fprintf(stderr,"out of memory\n");
     223  	xmlFreeDoc(doc);
     224  	return(NULL);
     225      }
     226      memset(ret, 0, sizeof(gJob));
     227  
     228      /*
     229       * Now, walk the tree.
     230       */
     231      /* First level we expect just Jobs */
     232      cur = cur->xmlChildrenNode;
     233      while ( cur && xmlIsBlankNode ( cur ) ) {
     234  	cur = cur -> next;
     235      }
     236      if ( cur == 0 ) {
     237  	xmlFreeDoc(doc);
     238  	free(ret);
     239  	return ( NULL );
     240      }
     241      if ((xmlStrcmp(cur->name, (const xmlChar *) "Jobs")) || (cur->ns != ns)) {
     242          fprintf(stderr,"document of the wrong type, was '%s', Jobs expected",
     243  		cur->name);
     244  	fprintf(stderr,"xmlDocDump follows\n");
     245  #ifdef LIBXML_OUTPUT_ENABLED
     246  	xmlDocDump ( stderr, doc );
     247  	fprintf(stderr,"xmlDocDump finished\n");
     248  #endif /* LIBXML_OUTPUT_ENABLED */
     249  	xmlFreeDoc(doc);
     250  	free(ret);
     251  	return(NULL);
     252      }
     253  
     254      /* Second level is a list of Job, but be laxist */
     255      cur = cur->xmlChildrenNode;
     256      while (cur != NULL) {
     257          if ((!xmlStrcmp(cur->name, (const xmlChar *) "Job")) &&
     258  	    (cur->ns == ns)) {
     259  	    curjob = parseJob(doc, ns, cur);
     260  	    if (curjob != NULL)
     261  	        ret->jobs[ret->nbJobs++] = curjob;
     262              if (ret->nbJobs >= 500) break;
     263  	}
     264  	cur = cur->next;
     265      }
     266  
     267      return(ret);
     268  }
     269  
     270  static void
     271  handleGjob(gJobPtr cur) {
     272      int i;
     273  
     274      /*
     275       * Do whatever you want and free the structure.
     276       */
     277      printf("%d Jobs registered\n", cur->nbJobs);
     278      for (i = 0; i < cur->nbJobs; i++) printJob(cur->jobs[i]);
     279  }
     280  
     281  int main(int argc, char **argv) {
     282      int i;
     283      gJobPtr cur;
     284  
     285      /* COMPAT: Do not generate nodes for formatting spaces */
     286      LIBXML_TEST_VERSION
     287  
     288      for (i = 1; i < argc ; i++) {
     289  	cur = parseGjobFile(argv[i]);
     290  	if ( cur )
     291  	  handleGjob(cur);
     292  	else
     293  	  fprintf( stderr, "Error parsing file '%s'\n", argv[i]);
     294  
     295      }
     296  
     297      /* Clean up everything else before quitting. */
     298      xmlCleanupParser();
     299  
     300      return(0);
     301  }