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