使用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
笔者在编译成功后,运行的时候遇到过如下的一个错误
“无法定位程序输入点gzdirect于动态链接库zlib1.dll”
解决办法是使用http://www.zlib.net/下载的最新的zlib1.dll替换WINDOWS/system32文件夹下的zlib1.dll (window下优先使用system32下的这个dll,而在安装某些软件时会将它们的zlib1.dll放到system32中,造成版本过低)
运行结果:
附gjobread.c和gjobs.xml源码
/*
* 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> /*
* 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>
#include <libxml/parser.h> #define DEBUG(x) printf(x) /*
* A person record
* an xmlChar * is really an UTF8 encoded char string (0 terminated)
*/
typedef struct person {
xmlChar *name;
xmlChar *email;
xmlChar *company;
xmlChar *organisation;
xmlChar *smail;
xmlChar *webPage;
xmlChar *phone;
} person, *personPtr; /*
* And the code needed to parse it
*/
static personPtr
parsePerson(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
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, , sizeof(person)); /* We don't care what the top level element name is */
/* COMPAT xmlChildrenNode is a macro unifying libxml1 and libxml2 names */
cur = cur->xmlChildrenNode;
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)"Person")) &&
(cur->ns == ns))
ret->name = xmlNodeListGetString(doc, cur->xmlChildrenNode, );
if ((!xmlStrcmp(cur->name, (const xmlChar *)"Email")) &&
(cur->ns == ns))
ret->email = xmlNodeListGetString(doc, cur->xmlChildrenNode, );
cur = cur->next;
} return(ret);
} /*
* and to print it
*/
static void
printPerson(personPtr cur) {
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 {
xmlChar *projectID;
xmlChar *application;
xmlChar *category;
personPtr contact;
int nbDevelopers;
personPtr developers[]; /* using dynamic alloc is left as an exercise */
} job, *jobPtr; /*
* And the code needed to parse it
*/
static jobPtr
parseJob(xmlDocPtr doc, xmlNsPtr ns, xmlNodePtr cur) {
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, , sizeof(job)); /* We don't care what the top level element name is */
cur = cur->xmlChildrenNode;
while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *) "Project")) &&
(cur->ns == ns)) {
ret->projectID = xmlGetProp(cur, (const xmlChar *) "ID");
if (ret->projectID == NULL) {
fprintf(stderr, "Project has no ID\n");
}
}
if ((!xmlStrcmp(cur->name, (const xmlChar *) "Application")) &&
(cur->ns == ns))
ret->application =
xmlNodeListGetString(doc, cur->xmlChildrenNode, );
if ((!xmlStrcmp(cur->name, (const xmlChar *) "Category")) &&
(cur->ns == ns))
ret->category =
xmlNodeListGetString(doc, cur->xmlChildrenNode, );
if ((!xmlStrcmp(cur->name, (const xmlChar *) "Contact")) &&
(cur->ns == ns))
ret->contact = parsePerson(doc, ns, cur);
cur = cur->next;
} return(ret);
} /*
* and to print it
*/
static void
printJob(jobPtr cur) {
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 = ;i < cur->nbDevelopers;i++) printPerson(cur->developers[i]);
printf("======= \n");
} /*
* A pool of Gnome Jobs
*/
typedef struct gjob {
int nbJobs;
jobPtr jobs[]; /* using dynamic alloc is left as an exercise */
} gJob, *gJobPtr; static gJobPtr
parseGjobFile(char *filename) {
xmlDocPtr doc;
gJobPtr ret;
jobPtr curjob;
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
*/ cur = xmlDocGetRootElement(doc);
if (cur == NULL) {
fprintf(stderr,"empty document\n");
xmlFreeDoc(doc);
return(NULL);
}
ns = xmlSearchNsByHref(doc, cur,
(const xmlChar *) "http://www.gnome.org/some-location");
if (ns == NULL) {
fprintf(stderr,
"document of the wrong type, GJob Namespace not found\n");
xmlFreeDoc(doc);
return(NULL);
}
if (xmlStrcmp(cur->name, (const xmlChar *) "Helping")) {
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, , sizeof(gJob)); /*
* Now, walk the tree.
*/
/* First level we expect just Jobs */
cur = cur->xmlChildrenNode;
while ( cur && xmlIsBlankNode ( cur ) )
{
cur = cur -> next;
}
if ( cur == )
return ( NULL );
if ((xmlStrcmp(cur->name, (const xmlChar *) "Jobs")) || (cur->ns != ns)) {
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");
xmlFreeDoc(doc);
free(ret);
return(NULL);
} /* Second level is a list of Job, but be laxist */
cur = cur->xmlChildrenNode;
while (cur != NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *) "Job")) &&
(cur->ns == ns)) {
curjob = parseJob(doc, ns, cur);
if (curjob != NULL)
ret->jobs[ret->nbJobs++] = curjob;
if (ret->nbJobs >= ) break;
}
cur = cur->next;
} return(ret);
} static void
handleGjob(gJobPtr cur) {
int i; /*
* Do whatever you want and free the structure.
*/
printf("%d Jobs registered\n", cur->nbJobs);
for (i = ; i < cur->nbJobs; i++) printJob(cur->jobs[i]);
} int main(int argc, char **argv) {
int i;
gJobPtr cur; /* COMPAT: Do not genrate nodes for formatting spaces */
LIBXML_TEST_VERSION
xmlKeepBlanksDefault(); for (i = ; i < argc ; i++) {
cur = parseGjobFile(argv[i]);
if ( cur )
handleGjob(cur);
else
fprintf( stderr, "Error parsing file '%s'\n", argv[i]); } /* Clean up everything else before quitting. */
xmlCleanupParser(); return();
}
gjobread.c
<?xml version="1.0"?>
<gjob:Helping xmlns:gjob="http://www.gnome.org/some-location">
<gjob:Jobs> <gjob:Job>
<gjob:Project ID="3"/>
<gjob:Application>GBackup</gjob:Application>
<gjob:Category>Development</gjob:Category> <gjob:Update>
<gjob:Status>Open</gjob:Status>
<gjob:Modified>Mon, 07 Jun 1999 20:27:45 -0400 MET DST</gjob:Modified>
<gjob:Salary>USD 0.00</gjob:Salary>
</gjob:Update> <gjob:Developers>
<gjob:Developer>
</gjob:Developer>
</gjob:Developers> <gjob:Contact>
<gjob:Person>Nathan Clemons</gjob:Person>
<gjob:Email>nathan@windsofstorm.net</gjob:Email>
<gjob:Company>
</gjob:Company>
<gjob:Organisation>
</gjob:Organisation>
<gjob:Webpage>
</gjob:Webpage>
<gjob:Snailmail>
</gjob:Snailmail>
<gjob:Phone>
</gjob:Phone>
</gjob:Contact> <gjob:Requirements>
The program should be released as free software, under the GPL.
</gjob:Requirements> <gjob:Skills>
</gjob:Skills> <gjob:Details>
A GNOME based system that will allow a superuser to configure
compressed and uncompressed files and/or file systems to be backed
up with a supported media in the system. This should be able to
perform via find commands generating a list of files that are passed
to tar, dd, cpio, cp, gzip, etc., to be directed to the tape machine
or via operations performed on the filesystem itself. Email
notification and GUI status display very important.
</gjob:Details> </gjob:Job> </gjob:Jobs>
</gjob:Helping>
gjobs.xml
使用libxml2进行xml开发(一)的更多相关文章
- Spring_IoC注解开发和AOP的XML开发(学习笔记2)
一:IoC注解开发 1,在applicationContext.xml中需要引入context约束 <beans xmlns="http://www.springframework.o ...
- TZ_05_Spring_事物的xml开发和annotation开发
1.Spring_事物的xml开发 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=& ...
- 使用Kotlin&Anko, 扔掉XML开发Android应用
尝鲜使用Kotlin写了一段时间Android.说大幅度的减少了Java代码一点不夸张.用Java的时候动不动就new一个OnClickListener()匿名类,动不动就类型转换的地方都可以省下很多 ...
- C#序列化xml,开发常用
序列化操作对于开发人员来说最熟悉不过了. 序列化分为:序列化和反序列化. 序列化名词解释:序列化是将对象状态转换为可保持或传输的格式的过程. 与序列化相对的是反序列化,它将流转换为对象.这两个过程结合 ...
- [libxml2]_[XML处理]_[使用libxml2的xpath特性修改xml文件内容]
场景: 1.在软件需要保存一些配置项时,使用数据库的话比较复杂,查看内容也不容易.纯文本文件对utf8字符支持也不好. 2.这时候使用xml是最佳选择,使用跨平台库libxml2. 3.基于xpath ...
- Spring中AOP的基于xml开发和配置
pom文件: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http ...
- android开发中eclipse里xml开发的自动提示和使用帮助快捷键提示
Eclipse Android 代码自动提示功能 Eclipse for android 设置代码提示功能 打 开 Eclipse 依次选择 Window > Preferences > ...
- MFC使用自带的MSXML6.dll解析xml(开发环境vc2010)
程序是win32控制台程序 // msxml.cpp : 定义控制台应用程序的入口点. #include "stdafx.h" #include <iostream> ...
- TZ_03_mybatis的xml开发
1.通过Student.xml编写sql来操作数据库 1>insert语句插入后返回主键 加入标签useGeneratedKeys=“true” keyProperty=“oid” 中 keyP ...
随机推荐
- iOS - OC - 字典快速遍历
1. [dic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop ...
- ubuntu 安装 google Gtest
1.安装源代码 在ubuntu的桌面上,右键选择打开终端,在终端中输入如下命令: $ sudo apt-get install libgtest-dev 下载源码后,apt将会在目录/usr/src/ ...
- PAT 1010 一元多项式求导 (25)(STL-map+思路)
1010 一元多项式求导 (25)(25 分)提问 设计函数求一元多项式的导数.(注:x^n^(n为整数)的一阶导数为n*x^n-1^.) 输入格式:以指数递降方式输入多项式非零项系数和指数(绝对值均 ...
- Eclipse下配置TinyOS开发环境
通过给Eclipse安装Yeti 2 - TinyOS 2 Plugin for Eclipse来配置TinyOS IDE,从而可建立TinyOS Project Yeti 2的介绍请参考网站:htt ...
- php调java接口
1.下载二进制的 JavaBridge.jar包.java/Java.inc库文件,下载地址:http://php-java-bridge.sourceforge.net/pjb/download.p ...
- python之web开发利器
http://docs.jinkan.org/docs/flask/ https://www.djangoproject.com/
- [转载红鱼儿]Delphi XE7 update1进步太大了
写以下的文字是怀着无比兴奋的心情写的,急于同朋友们分享XE7的进步! 1.更新的bug列表并不全 通过bug修正列表及发布的消息,可以看到up1修正了很多bug,正如我所说,有些bug并没有写到发布的 ...
- kbmMWEncodeEscapes 中汉字编码的问题及解决办法
kbmMWEncodeEscapes 是kbmmw 里面的一个函数,用来对URL 中的汉字进行编码,例如 http://127.0.0.1/getname?name=春节,由于'春节'是汉字,浏览器向 ...
- 2018.07.31 POJ1741Tree(点分治)
传送门 只是来贴一个点分治的板子(年轻时候写的丑别介意). 代码: #include<cstdio> #include<cstring> #include<algorit ...
- AVL树C++实现
1. AVL 树本质上还是一棵二叉搜索树,它的特点是: 本身首先是一棵二叉搜索树. 带有平衡条件: 每个结点的左右子树的高度之差的绝对值(平衡因子) 最多为 1. 2. 数据结构定义 AVL树节点类: ...