source: trunk/third/libxml2/example/gjobread.c @ 20735

Revision 20735, 7.4 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20734, which included commits to RCS files with non-trunk default branches.
Line 
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 */
32typedef 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 */
45static personPtr
46parsePerson(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
47    personPtr ret = NULL;
48
49DEBUG("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 */
79static void
80printPerson(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 */
96typedef 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 */
108static jobPtr
109parseJob(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
110    jobPtr ret = NULL;
111
112DEBUG("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 */
154static void
155printJob(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 */
173typedef struct gjob {
174    int nbJobs;
175    jobPtr jobs[500]; /* using dynamic alloc is left as an exercise */
176} gJob, *gJobPtr;
177
178
179static gJobPtr
180parseGjobFile(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      {
242        cur = cur -> next;
243      }
244    if ( cur == 0 )
245      return ( NULL );
246    if ((xmlStrcmp(cur->name, (const xmlChar *) "Jobs")) || (cur->ns != ns)) {
247        fprintf(stderr,"document of the wrong type, was '%s', Jobs expected",
248                cur->name);
249        fprintf(stderr,"xmlDocDump follows\n");
250#ifdef LIBXML_OUTPUT_ENABLED
251        xmlDocDump ( stderr, doc );
252        fprintf(stderr,"xmlDocDump finished\n");
253#endif /* LIBXML_OUTPUT_ENABLED */
254        xmlFreeDoc(doc);
255        free(ret);
256        return(NULL);
257    }
258
259    /* Second level is a list of Job, but be laxist */
260    cur = cur->xmlChildrenNode;
261    while (cur != NULL) {
262        if ((!xmlStrcmp(cur->name, (const xmlChar *) "Job")) &&
263            (cur->ns == ns)) {
264            curjob = parseJob(doc, ns, cur);
265            if (curjob != NULL)
266                ret->jobs[ret->nbJobs++] = curjob;
267            if (ret->nbJobs >= 500) break;
268        }
269        cur = cur->next;
270    }
271
272    return(ret);
273}
274
275static void
276handleGjob(gJobPtr cur) {
277    int i;
278
279    /*
280     * Do whatever you want and free the structure.
281     */
282    printf("%d Jobs registered\n", cur->nbJobs);
283    for (i = 0; i < cur->nbJobs; i++) printJob(cur->jobs[i]);
284}
285
286int main(int argc, char **argv) {
287    int i;
288    gJobPtr cur;
289
290    /* COMPAT: Do not genrate nodes for formatting spaces */
291    LIBXML_TEST_VERSION
292    xmlKeepBlanksDefault(0);
293
294    for (i = 1; i < argc ; i++) {
295        cur = parseGjobFile(argv[i]);
296        if ( cur )
297          handleGjob(cur);
298        else
299          fprintf( stderr, "Error parsing file '%s'\n", argv[i]);
300
301    }
302
303    /* Clean up everything else before quitting. */
304    xmlCleanupParser();
305
306    return(0);
307}
Note: See TracBrowser for help on using the repository browser.