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>