Annotation of embedaddon/libxml2/example/gjobread.c, revision 1.1.1.1
1.1 misho 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) {
181: xmlDocPtr doc;
182: gJobPtr ret;
183: jobPtr curjob;
184: xmlNsPtr ns;
185: xmlNodePtr cur;
186:
187: #ifdef LIBXML_SAX1_ENABLED
188: /*
189: * build an XML tree from a the file;
190: */
191: doc = xmlParseFile(filename);
192: if (doc == NULL) return(NULL);
193: #else
194: /*
195: * the library has been compiled without some of the old interfaces
196: */
197: return(NULL);
198: #endif /* LIBXML_SAX1_ENABLED */
199:
200: /*
201: * Check the document is of the right kind
202: */
203:
204: cur = xmlDocGetRootElement(doc);
205: if (cur == NULL) {
206: fprintf(stderr,"empty document\n");
207: xmlFreeDoc(doc);
208: return(NULL);
209: }
210: ns = xmlSearchNsByHref(doc, cur,
211: (const xmlChar *) "http://www.gnome.org/some-location");
212: if (ns == NULL) {
213: fprintf(stderr,
214: "document of the wrong type, GJob Namespace not found\n");
215: xmlFreeDoc(doc);
216: return(NULL);
217: }
218: if (xmlStrcmp(cur->name, (const xmlChar *) "Helping")) {
219: fprintf(stderr,"document of the wrong type, root node != Helping");
220: xmlFreeDoc(doc);
221: return(NULL);
222: }
223:
224: /*
225: * Allocate the structure to be returned.
226: */
227: ret = (gJobPtr) malloc(sizeof(gJob));
228: if (ret == NULL) {
229: fprintf(stderr,"out of memory\n");
230: xmlFreeDoc(doc);
231: return(NULL);
232: }
233: memset(ret, 0, sizeof(gJob));
234:
235: /*
236: * Now, walk the tree.
237: */
238: /* First level we expect just Jobs */
239: cur = cur->xmlChildrenNode;
240: while ( cur && xmlIsBlankNode ( cur ) ) {
241: cur = cur -> next;
242: }
243: if ( cur == 0 ) {
244: xmlFreeDoc(doc);
245: free(ret);
246: return ( NULL );
247: }
248: if ((xmlStrcmp(cur->name, (const xmlChar *) "Jobs")) || (cur->ns != ns)) {
249: fprintf(stderr,"document of the wrong type, was '%s', Jobs expected",
250: cur->name);
251: fprintf(stderr,"xmlDocDump follows\n");
252: #ifdef LIBXML_OUTPUT_ENABLED
253: xmlDocDump ( stderr, doc );
254: fprintf(stderr,"xmlDocDump finished\n");
255: #endif /* LIBXML_OUTPUT_ENABLED */
256: xmlFreeDoc(doc);
257: free(ret);
258: return(NULL);
259: }
260:
261: /* Second level is a list of Job, but be laxist */
262: cur = cur->xmlChildrenNode;
263: while (cur != NULL) {
264: if ((!xmlStrcmp(cur->name, (const xmlChar *) "Job")) &&
265: (cur->ns == ns)) {
266: curjob = parseJob(doc, ns, cur);
267: if (curjob != NULL)
268: ret->jobs[ret->nbJobs++] = curjob;
269: if (ret->nbJobs >= 500) break;
270: }
271: cur = cur->next;
272: }
273:
274: return(ret);
275: }
276:
277: static void
278: handleGjob(gJobPtr cur) {
279: int i;
280:
281: /*
282: * Do whatever you want and free the structure.
283: */
284: printf("%d Jobs registered\n", cur->nbJobs);
285: for (i = 0; i < cur->nbJobs; i++) printJob(cur->jobs[i]);
286: }
287:
288: int main(int argc, char **argv) {
289: int i;
290: gJobPtr cur;
291:
292: /* COMPAT: Do not genrate nodes for formatting spaces */
293: LIBXML_TEST_VERSION
294: xmlKeepBlanksDefault(0);
295:
296: for (i = 1; i < argc ; i++) {
297: cur = parseGjobFile(argv[i]);
298: if ( cur )
299: handleGjob(cur);
300: else
301: fprintf( stderr, "Error parsing file '%s'\n", argv[i]);
302:
303: }
304:
305: /* Clean up everything else before quitting. */
306: xmlCleanupParser();
307:
308: return(0);
309: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>