使用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(已经添加到MinGWlib下了),我们可以用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
");
 50     /*
 51      * allocate the struct
 52      */
 53     ret = (personPtr) malloc(sizeof(person));
 54     if (ret == NULL) {
 55         fprintf(stderr,"out of memory
");
 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
");
 83     if (cur->name) printf("    name: %s
", cur->name);
 84     if (cur->email) printf("    email: %s
", cur->email);
 85     if (cur->company) printf("    company: %s
", cur->company);
 86     if (cur->organisation) printf("    organisation: %s
", cur->organisation);
 87     if (cur->smail) printf("    smail: %s
", cur->smail);
 88     if (cur->webPage) printf("    Web: %s
", cur->webPage);
 89     if (cur->phone) printf("    phone: %s
", cur->phone);
 90     printf("------
");
 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
");
113     /*
114      * allocate the struct
115      */
116     ret = (jobPtr) malloc(sizeof(job));
117     if (ret == NULL) {
118         fprintf(stderr,"out of memory
");
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
");
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
");
160     if (cur->projectID != NULL) printf("projectID: %s
", cur->projectID);
161     if (cur->application != NULL) printf("application: %s
", cur->application);
162     if (cur->category != NULL) printf("category: %s
", cur->category);
163     if (cur->contact != NULL) printPerson(cur->contact);
164     printf("%d developers
", cur->nbDevelopers);
165 
166     for (i = 0;i < cur->nbDevelopers;i++) printPerson(cur->developers[i]);
167     printf("======= 
");
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     /*
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 kind
195      */
196     
197     cur = xmlDocGetRootElement(doc);
198     if (cur == NULL) {
199         fprintf(stderr,"empty document
");
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
");
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
");
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
");
243     xmlDocDump ( stderr, doc );
244     fprintf(stderr,"xmlDocDump finished
");
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 void
267 handleGjob(gJobPtr cur) {
268     int i;
269 
270     /*
271      * Do whatever you want and free the structure.
272      */
273     printf("%d Jobs registered
", 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_VERSION
283     xmlKeepBlanksDefault(0);
284 
285     for (i = 1; i < argc ; i++) {
286     cur = parseGjobFile(argv[i]);
287     if ( cur )
288       handleGjob(cur);
289     else
290       fprintf( stderr, "Error parsing file '%s'
", 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
原文地址:https://www.cnblogs.com/lyhero11/p/3836039.html