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