File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / example / gjobread.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:37:58 2012 UTC (12 years, 5 months ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_9_1p0, v2_9_1, v2_8_0p0, v2_8_0, v2_7_8, HEAD
libxml2

    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>