1999-06-13 18:37:07 +04:00
/*
* 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>
2000-06-29 03:40:59 +04:00
/*
* This example should compile and run indifferently with libxml - 1.8 .8 +
* and libxml2 - 2.1 .0 +
* Check the COMPAT comments below
*/
/*
* COMPAT using xml - config - - cflags to get the include path this will
* work with both
*/
# include <libxml/xmlmemory.h>
2000-05-06 12:11:19 +04:00
# include <libxml/parser.h>
1999-06-13 18:37:07 +04:00
# define DEBUG(x) printf(x)
/*
* A person record
2001-01-25 16:55:35 +03:00
* an xmlChar * is really an UTF8 encoded char string ( 0 terminated )
1999-06-13 18:37:07 +04:00
*/
typedef struct person {
2001-01-25 16:55:35 +03:00
xmlChar * name ;
xmlChar * email ;
xmlChar * company ;
xmlChar * organisation ;
xmlChar * smail ;
xmlChar * webPage ;
xmlChar * phone ;
1999-06-13 18:37:07 +04:00
} person , * personPtr ;
/*
* And the code needed to parse it
*/
2001-03-24 20:00:36 +03:00
static personPtr
parsePerson ( xmlDocPtr doc , xmlNsPtr ns , xmlNodePtr cur ) {
1999-06-13 18:37:07 +04:00
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 */
2000-06-29 03:40:59 +04:00
/* COMPAT xmlChildrenNode is a macro unifying libxml1 and libxml2 names */
cur = cur - > xmlChildrenNode ;
1999-06-13 18:37:07 +04:00
while ( cur ! = NULL ) {
2001-01-25 16:55:35 +03:00
if ( ( ! xmlStrcmp ( cur - > name , ( const xmlChar * ) " Person " ) ) & &
( cur - > ns = = ns ) )
2000-06-29 03:40:59 +04:00
ret - > name = xmlNodeListGetString ( doc , cur - > xmlChildrenNode , 1 ) ;
2001-01-25 16:55:35 +03:00
if ( ( ! xmlStrcmp ( cur - > name , ( const xmlChar * ) " Email " ) ) & &
( cur - > ns = = ns ) )
2000-06-29 03:40:59 +04:00
ret - > email = xmlNodeListGetString ( doc , cur - > xmlChildrenNode , 1 ) ;
1999-06-13 18:37:07 +04:00
cur = cur - > next ;
}
return ( ret ) ;
}
/*
* and to print it
*/
2001-03-24 20:00:36 +03:00
static void
printPerson ( personPtr cur ) {
1999-06-13 18:37:07 +04:00
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 {
2001-01-25 16:55:35 +03:00
xmlChar * projectID ;
xmlChar * application ;
xmlChar * category ;
1999-06-13 18:37:07 +04:00
personPtr contact ;
int nbDevelopers ;
personPtr developers [ 100 ] ; /* using dynamic alloc is left as an exercise */
} job , * jobPtr ;
/*
* And the code needed to parse it
*/
2001-03-24 20:00:36 +03:00
static jobPtr
parseJob ( xmlDocPtr doc , xmlNsPtr ns , xmlNodePtr cur ) {
1999-06-13 18:37:07 +04:00
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 */
2000-06-29 03:40:59 +04:00
cur = cur - > xmlChildrenNode ;
1999-06-13 18:37:07 +04:00
while ( cur ! = NULL ) {
2001-01-25 16:55:35 +03:00
if ( ( ! xmlStrcmp ( cur - > name , ( const xmlChar * ) " Project " ) ) & &
( cur - > ns = = ns ) ) {
ret - > projectID = xmlGetProp ( cur , ( const xmlChar * ) " ID " ) ;
1999-06-13 18:37:07 +04:00
if ( ret - > projectID = = NULL ) {
fprintf ( stderr , " Project has no ID \n " ) ;
}
}
2001-01-25 16:55:35 +03:00
if ( ( ! xmlStrcmp ( cur - > name , ( const xmlChar * ) " Application " ) ) & &
( cur - > ns = = ns ) )
ret - > application =
xmlNodeListGetString ( doc , cur - > xmlChildrenNode , 1 ) ;
if ( ( ! xmlStrcmp ( cur - > name , ( const xmlChar * ) " Category " ) ) & &
( cur - > ns = = ns ) )
ret - > category =
xmlNodeListGetString ( doc , cur - > xmlChildrenNode , 1 ) ;
if ( ( ! xmlStrcmp ( cur - > name , ( const xmlChar * ) " Contact " ) ) & &
( cur - > ns = = ns ) )
1999-06-13 18:37:07 +04:00
ret - > contact = parsePerson ( doc , ns , cur ) ;
cur = cur - > next ;
}
return ( ret ) ;
}
/*
* and to print it
*/
2001-03-24 20:00:36 +03:00
static void
printJob ( jobPtr cur ) {
1999-06-13 18:37:07 +04:00
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 ;
2001-03-24 20:00:36 +03:00
static gJobPtr
parseGjobFile ( char * filename ) {
1999-06-13 18:37:07 +04:00
xmlDocPtr doc ;
gJobPtr ret ;
2001-03-24 20:00:36 +03:00
jobPtr curjob ;
1999-06-13 18:37:07 +04:00
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
*/
2000-05-06 12:11:19 +04:00
cur = xmlDocGetRootElement ( doc ) ;
1999-06-13 18:37:07 +04:00
if ( cur = = NULL ) {
fprintf ( stderr , " empty document \n " ) ;
xmlFreeDoc ( doc ) ;
return ( NULL ) ;
}
2001-01-25 16:55:35 +03:00
ns = xmlSearchNsByHref ( doc , cur ,
( const xmlChar * ) " http://www.gnome.org/some-location " ) ;
1999-06-13 18:37:07 +04:00
if ( ns = = NULL ) {
fprintf ( stderr ,
" document of the wrong type, GJob Namespace not found \n " ) ;
xmlFreeDoc ( doc ) ;
return ( NULL ) ;
}
2001-01-25 16:55:35 +03:00
if ( xmlStrcmp ( cur - > name , ( const xmlChar * ) " Helping " ) ) {
1999-06-13 18:37:07 +04:00
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 */
2000-06-29 03:40:59 +04:00
cur = cur - > xmlChildrenNode ;
2000-05-06 12:11:19 +04:00
while ( cur & & xmlIsBlankNode ( cur ) )
{
cur = cur - > next ;
}
if ( cur = = 0 )
return ( NULL ) ;
2001-01-25 16:55:35 +03:00
if ( ( xmlStrcmp ( cur - > name , ( const xmlChar * ) " Jobs " ) ) | | ( cur - > ns ! = ns ) ) {
2000-05-06 12:11:19 +04:00
fprintf ( stderr , " document of the wrong type, was '%s', Jobs expected " ,
cur - > name ) ;
fprintf ( stderr , " xmlDocDump follows \n " ) ;
xmlDocDump ( stderr , doc ) ;
fprintf ( stderr , " xmlDocDump finished \n " ) ;
1999-06-13 18:37:07 +04:00
xmlFreeDoc ( doc ) ;
free ( ret ) ;
return ( NULL ) ;
}
/* Second level is a list of Job, but be laxist */
2000-06-29 03:40:59 +04:00
cur = cur - > xmlChildrenNode ;
1999-06-13 18:37:07 +04:00
while ( cur ! = NULL ) {
2001-01-25 16:55:35 +03:00
if ( ( ! xmlStrcmp ( cur - > name , ( const xmlChar * ) " Job " ) ) & &
( cur - > ns = = ns ) ) {
2001-03-24 20:00:36 +03:00
curjob = parseJob ( doc , ns , cur ) ;
if ( curjob ! = NULL )
ret - > jobs [ ret - > nbJobs + + ] = curjob ;
1999-06-13 18:37:07 +04:00
if ( ret - > nbJobs > = 500 ) break ;
}
cur = cur - > next ;
}
return ( ret ) ;
}
2001-03-24 20:00:36 +03:00
static void
handleGjob ( gJobPtr cur ) {
1999-06-13 18:37:07 +04:00
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 ;
2000-06-29 03:40:59 +04:00
/* COMPAT: Do not genrate nodes for formatting spaces */
2000-06-29 04:43:27 +04:00
LIBXML_TEST_VERSION
2000-06-29 03:40:59 +04:00
xmlKeepBlanksDefault ( 0 ) ;
1999-06-13 18:37:07 +04:00
for ( i = 1 ; i < argc ; i + + ) {
cur = parseGjobFile ( argv [ i ] ) ;
2000-05-06 12:11:19 +04:00
if ( cur )
handleGjob ( cur ) ;
else
fprintf ( stderr , " Error parsing file '%s' \n " , argv [ i ] ) ;
1999-06-13 18:37:07 +04:00
}
2001-08-16 00:46:57 +04:00
/* Clean up everything else before quitting. */
xmlCleanupParser ( ) ;
1999-06-13 18:37:07 +04:00
return ( 0 ) ;
}