gjobread.c 7.5 KB

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