| /* |
| * gjobread.c : a small test program for gnome jobs XML format |
| * |
| * See Copyright for the status of this software. |
| * |
| * Daniel.Veillard@w3.org |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| |
| #include "parser.h" |
| |
| #define DEBUG(x) printf(x) |
| |
| /* |
| * A person record |
| */ |
| typedef struct person { |
| char *name; |
| char *email; |
| char *company; |
| char *organisation; |
| char *smail; |
| char *webPage; |
| char *phone; |
| } person, *personPtr; |
| |
| /* |
| * And the code needed to parse it |
| */ |
| personPtr parsePerson(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) { |
| personPtr ret = NULL; |
| |
| DEBUG("parsePerson\n"); |
| /* |
| * allocate the struct |
| */ |
| ret = (personPtr) malloc(sizeof(person)); |
| if (ret == NULL) { |
| fprintf(stderr,"out of memory\n"); |
| return(NULL); |
| } |
| memset(ret, 0, sizeof(person)); |
| |
| /* We don't care what the top level element name is */ |
| cur = cur->childs; |
| while (cur != NULL) { |
| if ((!strcmp(cur->name, "Person")) && (cur->ns == ns)) |
| ret->name = xmlNodeListGetString(doc, cur->childs, 1); |
| if ((!strcmp(cur->name, "Email")) && (cur->ns == ns)) |
| ret->email = xmlNodeListGetString(doc, cur->childs, 1); |
| cur = cur->next; |
| } |
| |
| return(ret); |
| } |
| |
| /* |
| * and to print it |
| */ |
| void printPerson(personPtr cur) { |
| if (cur == NULL) return; |
| printf("------ Person\n"); |
| if (cur->name) printf(" name: %s\n", cur->name); |
| if (cur->email) printf(" email: %s\n", cur->email); |
| if (cur->company) printf(" company: %s\n", cur->company); |
| if (cur->organisation) printf(" organisation: %s\n", cur->organisation); |
| if (cur->smail) printf(" smail: %s\n", cur->smail); |
| if (cur->webPage) printf(" Web: %s\n", cur->webPage); |
| if (cur->phone) printf(" phone: %s\n", cur->phone); |
| printf("------\n"); |
| } |
| |
| /* |
| * a Description for a Job |
| */ |
| typedef struct job { |
| char *projectID; |
| char *application; |
| char *category; |
| personPtr contact; |
| int nbDevelopers; |
| personPtr developers[100]; /* using dynamic alloc is left as an exercise */ |
| } job, *jobPtr; |
| |
| /* |
| * And the code needed to parse it |
| */ |
| jobPtr parseJob(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) { |
| jobPtr ret = NULL; |
| |
| DEBUG("parseJob\n"); |
| /* |
| * allocate the struct |
| */ |
| ret = (jobPtr) malloc(sizeof(job)); |
| if (ret == NULL) { |
| fprintf(stderr,"out of memory\n"); |
| return(NULL); |
| } |
| memset(ret, 0, sizeof(job)); |
| |
| /* We don't care what the top level element name is */ |
| cur = cur->childs; |
| while (cur != NULL) { |
| |
| if ((!strcmp(cur->name, "Project")) && (cur->ns == ns)) { |
| ret->projectID = xmlGetProp(cur, "ID"); |
| if (ret->projectID == NULL) { |
| fprintf(stderr, "Project has no ID\n"); |
| } |
| } |
| if ((!strcmp(cur->name, "Application")) && (cur->ns == ns)) |
| ret->application = xmlNodeListGetString(doc, cur->childs, 1); |
| if ((!strcmp(cur->name, "Category")) && (cur->ns == ns)) |
| ret->category = xmlNodeListGetString(doc, cur->childs, 1); |
| if ((!strcmp(cur->name, "Contact")) && (cur->ns == ns)) |
| ret->contact = parsePerson(doc, ns, cur); |
| cur = cur->next; |
| } |
| |
| return(ret); |
| } |
| |
| /* |
| * and to print it |
| */ |
| void printJob(jobPtr cur) { |
| int i; |
| |
| if (cur == NULL) return; |
| printf("======= Job\n"); |
| if (cur->projectID != NULL) printf("projectID: %s\n", cur->projectID); |
| if (cur->application != NULL) printf("application: %s\n", cur->application); |
| if (cur->category != NULL) printf("category: %s\n", cur->category); |
| if (cur->contact != NULL) printPerson(cur->contact); |
| printf("%d developers\n", cur->nbDevelopers); |
| |
| for (i = 0;i < cur->nbDevelopers;i++) printPerson(cur->developers[i]); |
| printf("======= \n"); |
| } |
| |
| /* |
| * A pool of Gnome Jobs |
| */ |
| typedef struct gjob { |
| int nbJobs; |
| jobPtr jobs[500]; /* using dynamic alloc is left as an exercise */ |
| } gJob, *gJobPtr; |
| |
| |
| gJobPtr parseGjobFile(char *filename) { |
| xmlDocPtr doc; |
| gJobPtr ret; |
| jobPtr job; |
| xmlNsPtr ns; |
| xmlNodePtr cur; |
| |
| /* |
| * build an XML tree from a the file; |
| */ |
| doc = xmlParseFile(filename); |
| if (doc == NULL) return(NULL); |
| |
| /* |
| * Check the document is of the right kind |
| */ |
| cur = doc->root; |
| if (cur == NULL) { |
| fprintf(stderr,"empty document\n"); |
| xmlFreeDoc(doc); |
| return(NULL); |
| } |
| ns = xmlSearchNsByHref(doc, cur, "http://www.gnome.org/some-location"); |
| if (ns == NULL) { |
| fprintf(stderr, |
| "document of the wrong type, GJob Namespace not found\n"); |
| xmlFreeDoc(doc); |
| return(NULL); |
| } |
| if (strcmp(cur->name, "Helping")) { |
| fprintf(stderr,"document of the wrong type, root node != Helping"); |
| xmlFreeDoc(doc); |
| return(NULL); |
| } |
| |
| /* |
| * Allocate the structure to be returned. |
| */ |
| ret = (gJobPtr) malloc(sizeof(gJob)); |
| if (ret == NULL) { |
| fprintf(stderr,"out of memory\n"); |
| xmlFreeDoc(doc); |
| return(NULL); |
| } |
| memset(ret, 0, sizeof(gJob)); |
| |
| /* |
| * Now, walk the tree. |
| */ |
| /* First level we expect just Jobs */ |
| cur = cur->childs; |
| if ((strcmp(cur->name, "Jobs")) || (cur->ns != ns)) { |
| fprintf(stderr,"document of the wrong type, Jobs expected"); |
| xmlFreeDoc(doc); |
| free(ret); |
| return(NULL); |
| } |
| |
| /* Second level is a list of Job, but be laxist */ |
| cur = cur->childs; |
| while (cur != NULL) { |
| if ((!strcmp(cur->name, "Job")) && (cur->ns == ns)) { |
| job = parseJob(doc, ns, cur); |
| if (job != NULL) |
| ret->jobs[ret->nbJobs++] = job; |
| if (ret->nbJobs >= 500) break; |
| } |
| cur = cur->next; |
| } |
| |
| return(ret); |
| } |
| |
| void handleGjob(gJobPtr cur) { |
| int i; |
| |
| /* |
| * Do whatever you want and free the structure. |
| */ |
| printf("%d Jobs registered\n", cur->nbJobs); |
| for (i = 0; i < cur->nbJobs; i++) printJob(cur->jobs[i]); |
| } |
| |
| int main(int argc, char **argv) { |
| int i; |
| gJobPtr cur; |
| |
| for (i = 1; i < argc ; i++) { |
| cur = parseGjobFile(argv[i]); |
| handleGjob(cur); |
| } |
| return(0); |
| } |