首页 > 代码库 > 使用libxml2进行xml开发(一)

使用libxml2进行xml开发(一)

   

(一)Windows下使用MinGW和Code::Blocks环境配置libxml2

    笔者此次是在windows 7下使用MinGW和Code::Blocks开发C程式的,手上的一个项目需要使用socket通讯接收远端主机发来的xml报文,使用C程式解析,所以需要配置libxml2。

    首先先到http://xmlsoft.org/sources/win32/下载好libxml2、iconv和zlib的包,并将其对应的bin、include、lib中的内容复制到MinGW对应的bin、include、lib目录中去(libxml2是基于iconv和zlib的

在CB中建立好一个工程后,在settings->compiler->linker settings中添加上述包中的lib(已经添加到MinGW\lib下了),我们可以用libxml2官方的一个例子来测试我们的配置:

将gjobs.xml放在工程文件夹中,将其设置为输入  Project->set programs‘ arguments

http://www.ualberta.ca/dept/aict/uts/software/solaris9/sparc/patches/solaris/9_Recommended/114014-18/SUNWlxmlS/reloc/usr/share/src/libxml2/example/gjobread.c

http://www.ualberta.ca/dept/aict/uts/software/solaris9/sparc/patches/solaris/9_Recommended/114014-18/SUNWlxmlS/reloc/usr/share/src/libxml2/example/gjobs.xml

 

笔者在编译成功后,运行的时候遇到过如下的一个错误

“无法定位程序输入点gzdirect于动态链接库zlib1.dll”

 

解决办法是使用http://www.zlib.net/下载的最新的zlib1.dll替换WINDOWS/system32文件夹下的zlib1.dll (window下优先使用system32下的这个dll,而在安装某些软件时会将它们的zlib1.dll放到system32中,造成版本过低)

运行结果:

 

附gjobread.c和gjobs.xml源码

  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 it107  */108 static jobPtr109 parseJob(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {110     jobPtr ret = NULL;111 112 DEBUG("parseJob\n");113     /*114      * allocate the struct115      */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 it153  */154 static void155 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 Jobs172  */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 gJobPtr180 parseGjobFile(char *filename) {181     xmlDocPtr doc;182     gJobPtr ret;183     jobPtr curjob;184     xmlNsPtr ns;185     xmlNodePtr cur;186 187     /*188      * build an XML tree from a the file;189      */190     doc = xmlParseFile(filename);191     if (doc == NULL) return(NULL);192 193     /*194      * Check the document is of the right kind195      */196     197     cur = xmlDocGetRootElement(doc);198     if (cur == NULL) {199         fprintf(stderr,"empty document\n");200     xmlFreeDoc(doc);201     return(NULL);202     }203     ns = xmlSearchNsByHref(doc, cur,204         (const xmlChar *) "http://www.gnome.org/some-location");205     if (ns == NULL) {206         fprintf(stderr,207             "document of the wrong type, GJob Namespace not found\n");208     xmlFreeDoc(doc);209     return(NULL);210     }211     if (xmlStrcmp(cur->name, (const xmlChar *) "Helping")) {212         fprintf(stderr,"document of the wrong type, root node != Helping");213     xmlFreeDoc(doc);214     return(NULL);215     }216 217     /*218      * Allocate the structure to be returned.219      */220     ret = (gJobPtr) malloc(sizeof(gJob));221     if (ret == NULL) {222         fprintf(stderr,"out of memory\n");223     xmlFreeDoc(doc);224     return(NULL);225     }226     memset(ret, 0, sizeof(gJob));227 228     /*229      * Now, walk the tree.230      */231     /* First level we expect just Jobs */232     cur = cur->xmlChildrenNode;233     while ( cur && xmlIsBlankNode ( cur ) )234       {235     cur = cur -> next;236       }237     if ( cur == 0 )238       return ( NULL );239     if ((xmlStrcmp(cur->name, (const xmlChar *) "Jobs")) || (cur->ns != ns)) {240         fprintf(stderr,"document of the wrong type, was ‘%s‘, Jobs expected",241         cur->name);242     fprintf(stderr,"xmlDocDump follows\n");243     xmlDocDump ( stderr, doc );244     fprintf(stderr,"xmlDocDump finished\n");245     xmlFreeDoc(doc);246     free(ret);247     return(NULL);248     }249 250     /* Second level is a list of Job, but be laxist */251     cur = cur->xmlChildrenNode;252     while (cur != NULL) {253         if ((!xmlStrcmp(cur->name, (const xmlChar *) "Job")) &&254         (cur->ns == ns)) {255         curjob = parseJob(doc, ns, cur);256         if (curjob != NULL)257             ret->jobs[ret->nbJobs++] = curjob;258             if (ret->nbJobs >= 500) break;259     }260     cur = cur->next;261     }262 263     return(ret);264 }265 266 static void267 handleGjob(gJobPtr cur) {268     int i;269 270     /*271      * Do whatever you want and free the structure.272      */273     printf("%d Jobs registered\n", cur->nbJobs);274     for (i = 0; i < cur->nbJobs; i++) printJob(cur->jobs[i]);275 }276 277 int main(int argc, char **argv) {278     int i;279     gJobPtr cur;280 281     /* COMPAT: Do not genrate nodes for formatting spaces */282     LIBXML_TEST_VERSION283     xmlKeepBlanksDefault(0);284 285     for (i = 1; i < argc ; i++) {286     cur = parseGjobFile(argv[i]);287     if ( cur )288       handleGjob(cur);289     else290       fprintf( stderr, "Error parsing file ‘%s‘\n", argv[i]);291 292     }293 294     /* Clean up everything else before quitting. */295     xmlCleanupParser();296 297     return(0);298 }
gjobread.c
 1 <?xml version="1.0"?> 2 <gjob:Helping xmlns:gjob="http://www.gnome.org/some-location"> 3   <gjob:Jobs> 4  5     <gjob:Job> 6       <gjob:Project ID="3"/> 7       <gjob:Application>GBackup</gjob:Application> 8       <gjob:Category>Development</gjob:Category> 9 10       <gjob:Update>11     <gjob:Status>Open</gjob:Status>12     <gjob:Modified>Mon, 07 Jun 1999 20:27:45 -0400 MET DST</gjob:Modified>13         <gjob:Salary>USD 0.00</gjob:Salary>14       </gjob:Update>15 16       <gjob:Developers>17         <gjob:Developer>18         </gjob:Developer>19       </gjob:Developers>20 21       <gjob:Contact>22         <gjob:Person>Nathan Clemons</gjob:Person>23     <gjob:Email>nathan@windsofstorm.net</gjob:Email>24         <gjob:Company>25     </gjob:Company>26         <gjob:Organisation>27     </gjob:Organisation>28         <gjob:Webpage>29     </gjob:Webpage>30     <gjob:Snailmail>31     </gjob:Snailmail>32     <gjob:Phone>33     </gjob:Phone>34       </gjob:Contact>35 36       <gjob:Requirements>37       The program should be released as free software, under the GPL.38       </gjob:Requirements>39 40       <gjob:Skills>41       </gjob:Skills>42 43       <gjob:Details>44       A GNOME based system that will allow a superuser to configure 45       compressed and uncompressed files and/or file systems to be backed 46       up with a supported media in the system.  This should be able to 47       perform via find commands generating a list of files that are passed 48       to tar, dd, cpio, cp, gzip, etc., to be directed to the tape machine 49       or via operations performed on the filesystem itself. Email 50       notification and GUI status display very important.51       </gjob:Details>52 53     </gjob:Job>54 55   </gjob:Jobs>56 </gjob:Helping>
gjobs.xml