blob: 916fa53abcc1aa894cebc55c76231d5238f64a3d [file] [log] [blame]
Daniel Veillardbb2da581999-06-13 14:37:07 +00001/*
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
Daniel Veillardbe803962000-06-28 23:40:59 +000013/*
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>
Daniel Veillardf3029822000-05-06 08:11:19 +000024#include <libxml/parser.h>
Daniel Veillardbb2da581999-06-13 14:37:07 +000025
26#define DEBUG(x) printf(x)
27
28/*
29 * A person record
30 */
31typedef struct person {
32 char *name;
33 char *email;
34 char *company;
35 char *organisation;
36 char *smail;
37 char *webPage;
38 char *phone;
39} person, *personPtr;
40
41/*
42 * And the code needed to parse it
43 */
44personPtr parsePerson(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
45 personPtr ret = NULL;
46
47DEBUG("parsePerson\n");
48 /*
49 * allocate the struct
50 */
51 ret = (personPtr) malloc(sizeof(person));
52 if (ret == NULL) {
53 fprintf(stderr,"out of memory\n");
54 return(NULL);
55 }
56 memset(ret, 0, sizeof(person));
57
58 /* We don't care what the top level element name is */
Daniel Veillardbe803962000-06-28 23:40:59 +000059 /* COMPAT xmlChildrenNode is a macro unifying libxml1 and libxml2 names */
60 cur = cur->xmlChildrenNode;
Daniel Veillardbb2da581999-06-13 14:37:07 +000061 while (cur != NULL) {
62 if ((!strcmp(cur->name, "Person")) && (cur->ns == ns))
Daniel Veillardbe803962000-06-28 23:40:59 +000063 ret->name = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
Daniel Veillardbb2da581999-06-13 14:37:07 +000064 if ((!strcmp(cur->name, "Email")) && (cur->ns == ns))
Daniel Veillardbe803962000-06-28 23:40:59 +000065 ret->email = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
Daniel Veillardbb2da581999-06-13 14:37:07 +000066 cur = cur->next;
67 }
68
69 return(ret);
70}
71
72/*
73 * and to print it
74 */
75void printPerson(personPtr cur) {
76 if (cur == NULL) return;
77 printf("------ Person\n");
78 if (cur->name) printf(" name: %s\n", cur->name);
79 if (cur->email) printf(" email: %s\n", cur->email);
80 if (cur->company) printf(" company: %s\n", cur->company);
81 if (cur->organisation) printf(" organisation: %s\n", cur->organisation);
82 if (cur->smail) printf(" smail: %s\n", cur->smail);
83 if (cur->webPage) printf(" Web: %s\n", cur->webPage);
84 if (cur->phone) printf(" phone: %s\n", cur->phone);
85 printf("------\n");
86}
87
88/*
89 * a Description for a Job
90 */
91typedef struct job {
92 char *projectID;
93 char *application;
94 char *category;
95 personPtr contact;
96 int nbDevelopers;
97 personPtr developers[100]; /* using dynamic alloc is left as an exercise */
98} job, *jobPtr;
99
100/*
101 * And the code needed to parse it
102 */
103jobPtr parseJob(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
104 jobPtr ret = NULL;
105
106DEBUG("parseJob\n");
107 /*
108 * allocate the struct
109 */
110 ret = (jobPtr) malloc(sizeof(job));
111 if (ret == NULL) {
112 fprintf(stderr,"out of memory\n");
113 return(NULL);
114 }
115 memset(ret, 0, sizeof(job));
116
117 /* We don't care what the top level element name is */
Daniel Veillardbe803962000-06-28 23:40:59 +0000118 cur = cur->xmlChildrenNode;
Daniel Veillardbb2da581999-06-13 14:37:07 +0000119 while (cur != NULL) {
120
121 if ((!strcmp(cur->name, "Project")) && (cur->ns == ns)) {
122 ret->projectID = xmlGetProp(cur, "ID");
123 if (ret->projectID == NULL) {
124 fprintf(stderr, "Project has no ID\n");
125 }
126 }
127 if ((!strcmp(cur->name, "Application")) && (cur->ns == ns))
Daniel Veillardbe803962000-06-28 23:40:59 +0000128 ret->application = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
Daniel Veillardbb2da581999-06-13 14:37:07 +0000129 if ((!strcmp(cur->name, "Category")) && (cur->ns == ns))
Daniel Veillardbe803962000-06-28 23:40:59 +0000130 ret->category = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
Daniel Veillardbb2da581999-06-13 14:37:07 +0000131 if ((!strcmp(cur->name, "Contact")) && (cur->ns == ns))
132 ret->contact = parsePerson(doc, ns, cur);
133 cur = cur->next;
134 }
135
136 return(ret);
137}
138
139/*
140 * and to print it
141 */
142void printJob(jobPtr cur) {
143 int i;
144
145 if (cur == NULL) return;
146 printf("======= Job\n");
147 if (cur->projectID != NULL) printf("projectID: %s\n", cur->projectID);
148 if (cur->application != NULL) printf("application: %s\n", cur->application);
149 if (cur->category != NULL) printf("category: %s\n", cur->category);
150 if (cur->contact != NULL) printPerson(cur->contact);
151 printf("%d developers\n", cur->nbDevelopers);
152
153 for (i = 0;i < cur->nbDevelopers;i++) printPerson(cur->developers[i]);
154 printf("======= \n");
155}
156
157/*
158 * A pool of Gnome Jobs
159 */
160typedef struct gjob {
161 int nbJobs;
162 jobPtr jobs[500]; /* using dynamic alloc is left as an exercise */
163} gJob, *gJobPtr;
164
165
166gJobPtr parseGjobFile(char *filename) {
167 xmlDocPtr doc;
168 gJobPtr ret;
169 jobPtr job;
170 xmlNsPtr ns;
171 xmlNodePtr cur;
172
173 /*
174 * build an XML tree from a the file;
175 */
176 doc = xmlParseFile(filename);
177 if (doc == NULL) return(NULL);
178
179 /*
180 * Check the document is of the right kind
181 */
Daniel Veillardf3029822000-05-06 08:11:19 +0000182
Daniel Veillardf3029822000-05-06 08:11:19 +0000183 cur = xmlDocGetRootElement(doc);
Daniel Veillardbb2da581999-06-13 14:37:07 +0000184 if (cur == NULL) {
185 fprintf(stderr,"empty document\n");
186 xmlFreeDoc(doc);
187 return(NULL);
188 }
189 ns = xmlSearchNsByHref(doc, cur, "http://www.gnome.org/some-location");
190 if (ns == NULL) {
191 fprintf(stderr,
192 "document of the wrong type, GJob Namespace not found\n");
193 xmlFreeDoc(doc);
194 return(NULL);
195 }
196 if (strcmp(cur->name, "Helping")) {
197 fprintf(stderr,"document of the wrong type, root node != Helping");
198 xmlFreeDoc(doc);
199 return(NULL);
200 }
201
202 /*
203 * Allocate the structure to be returned.
204 */
205 ret = (gJobPtr) malloc(sizeof(gJob));
206 if (ret == NULL) {
207 fprintf(stderr,"out of memory\n");
208 xmlFreeDoc(doc);
209 return(NULL);
210 }
211 memset(ret, 0, sizeof(gJob));
212
213 /*
214 * Now, walk the tree.
215 */
216 /* First level we expect just Jobs */
Daniel Veillardbe803962000-06-28 23:40:59 +0000217 cur = cur->xmlChildrenNode;
Daniel Veillardf3029822000-05-06 08:11:19 +0000218 while ( cur && xmlIsBlankNode ( cur ) )
219 {
220 cur = cur -> next;
221 }
222 if ( cur == 0 )
223 return ( NULL );
Daniel Veillardbb2da581999-06-13 14:37:07 +0000224 if ((strcmp(cur->name, "Jobs")) || (cur->ns != ns)) {
Daniel Veillardf3029822000-05-06 08:11:19 +0000225 fprintf(stderr,"document of the wrong type, was '%s', Jobs expected",
226 cur->name);
227 fprintf(stderr,"xmlDocDump follows\n");
228 xmlDocDump ( stderr, doc );
229 fprintf(stderr,"xmlDocDump finished\n");
Daniel Veillardbb2da581999-06-13 14:37:07 +0000230 xmlFreeDoc(doc);
231 free(ret);
232 return(NULL);
233 }
234
235 /* Second level is a list of Job, but be laxist */
Daniel Veillardbe803962000-06-28 23:40:59 +0000236 cur = cur->xmlChildrenNode;
Daniel Veillardbb2da581999-06-13 14:37:07 +0000237 while (cur != NULL) {
238 if ((!strcmp(cur->name, "Job")) && (cur->ns == ns)) {
239 job = parseJob(doc, ns, cur);
240 if (job != NULL)
241 ret->jobs[ret->nbJobs++] = job;
242 if (ret->nbJobs >= 500) break;
243 }
244 cur = cur->next;
245 }
246
247 return(ret);
248}
249
250void handleGjob(gJobPtr cur) {
251 int i;
252
253 /*
254 * Do whatever you want and free the structure.
255 */
256 printf("%d Jobs registered\n", cur->nbJobs);
257 for (i = 0; i < cur->nbJobs; i++) printJob(cur->jobs[i]);
258}
259
260int main(int argc, char **argv) {
261 int i;
262 gJobPtr cur;
263
Daniel Veillardbe803962000-06-28 23:40:59 +0000264 /* COMPAT: Do not genrate nodes for formatting spaces */
265 xmlKeepBlanksDefault(0);
266
Daniel Veillardbb2da581999-06-13 14:37:07 +0000267 for (i = 1; i < argc ; i++) {
268 cur = parseGjobFile(argv[i]);
Daniel Veillardf3029822000-05-06 08:11:19 +0000269 if ( cur )
270 handleGjob(cur);
271 else
272 fprintf( stderr, "Error parsing file '%s'\n", argv[i]);
273
Daniel Veillardbb2da581999-06-13 14:37:07 +0000274 }
275 return(0);
276}