使用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  * [email protected]
  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     /*
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\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 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\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_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‘\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>[email protected]</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

使用libxml2进行xml开发(一)

时间: 2024-10-19 11:58:09

使用libxml2进行xml开发(一)的相关文章

android开发中eclipse里xml开发的自动提示和使用帮助快捷键提示

Eclipse Android 代码自动提示功能 Eclipse for android 设置代码提示功能 打 开 Eclipse 依次选择 Window > Preferences > Java > Editor - Content Assist > Auto activation triggers for Java ,设置框中默认是一个点, .abcdefghijklmnopqrstuvwxyz(, 打 开 Eclipse 依次选择 Window > Preference

[libxml2]_[XML处理]_[使用libxml2的xpath特性修改xml文件内容]

场景: 1.在软件需要保存一些配置项时,使用数据库的话比较复杂,查看内容也不容易.纯文本文件对utf8字符支持也不好. 2.这时候使用xml是最佳选择,使用跨平台库libxml2. 3.基于xpath的保存方式对保存局部内容非常方便. 4.参考例子xpath2.c 1 #include <stdio.h> 2 #include <assert.h> 3 #include <string> 4 #include <iostream> 5 #include &l

使用libxml2解析xml

book.xml <?xml version="1.0" encoding="UTF-8" ?> <books> <book2> <name id="1">c primer plus111</name> <author>unknow author</author> <date>unknow date</date> </book2>

Qt 直接构建XML开发web services客户端程序

client.h   client.cpp     :   XML发送与接收 service.h service.cpp  :   消息的发送与接收 message.h message.cpp    :   消息的构建 messageparser.h messageparser.cpp  :   消息的解析 calc.h calc.cpp    :   计算 add.h add.cpp    :   加法运算 源代码下载:http://download.csdn.net/detail/chenj

linux下使用libxml2实现对xml文件的读取及查询

由于项目需要,这两天在用C++做XML文件解析的工作.在linux下有个很方便的操作xml文件的库——libxml2,它提供了一套创建和查询xml文件的C语言的接口.这篇博客主要介绍如何使用libxml2读取并解析xml文件. 下载并安装libxml2 下载地址:ftp://xmlsoft.org/libxml2/ 下载最新的版本,我下载的是libxml2-2.9.1.tar.gz.下载后将文件解压到合适的位置,进入解压后的目录. 编译命令非常简单(注意:如果configure文件没有可执行权限

windows 系统在vs2010 中配置libxml2,及读取xml代码例子

1.先下载libxml2 (下载地址 http://download.csdn.net/detail/luoww1/8095273),里面包括了三个文件夹分别:zlib-1.2.3.win32 和iconv-1.9.2.win32 和libxml2-2.7.6.win32 2.将下载内容中的iconv.dll 和zlib1.dll 拷贝到C盘下的Windows文件夹中 3.在项目中新建include 文件夹,解压的到的libxml2和iconv中的include文件夹中的内容拷入到该includ

XMPPFramewok IOS 开发(一)——配置xcode

看了很多教程,有的很旧,有的写的太简单,而实际操作会出现很多编译报错,特此记下来供以后参考. 最好按照步骤一步步导入Framework,每做完一步都要编译一下,发现错误及时改正,否则到最后会很麻烦. 第一步 新建项目chatDemo 第二步 下载最新版XMPPFramewok 地址: https://github.com/robbiehanson/XMPPFramework 第三步 在chatDemo目录下新建目录3rd,在3rd目录下新建XMPP目录,如图所示 第四步 添加CocoaLumbe

android驱动开发第三、四章读书笔记

第三章讲解了git及git操作的基本命令 1.git是一款免费.开源的分布式版本控制系统,符合linux的开源思想,且相对于svn cvs等,git有自己的优势,且广受开发者欢迎 2.git的安装: apt-get install git apt-get install git-doc git-svn apt-get install git-email git-gui gitk 3.常见命令: man git—checkout   /  git help git-checkout    查看gi

使用由 Python 编写的 lxml 实现高性能 XML 解析

lxml 简介 Python 从来不出现 XML 库短缺的情况.从 2.0 版本开始,它就附带了 xml.dom.minidom 和相关的 pulldom 以及 Simple API for XML (SAX) 模块.从 2.4 开始,它附带了流行的 ElementTree API.此外,很多第三方库可以提供更高级别的或更具有 python 风格的接口. 尽管任何 XML 库都足够处理简单的 Document Object Model (DOM) 或小型文件的 SAX 解析,但开发人员越来越多碰