using libxml2
来源:互联网 发布:淘宝旗袍模特 编辑:程序博客网 时间:2024/06/04 18:16
本文转自CSDN:denny的专栏
清单 1. 一个简单的 XML 文件
LibXML2自身已经支持了中文编码.只是他的所有api处理的数据都是UTF-8类型的,所以只要在读入和写入数据时进行相应转换即可!代码1是使用linux下C API进行编码转换;代码2因为libxml2已融合了iconv,使用了libxml2的函数来进行编码转换.
/*
compile: gcc -I/usr/include/libxml2/ -lxml2 iconv.c
input:
test.xml
<?xml version="1.0" encoding="gb2312"?>
<parent>测试</parent>
output:
测试
1) iconv
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <arpa/inet.h>
#include <iconv.h>
char * Convert( char *encFrom, char *encTo, const char * in)
{
static char bufin[1024], bufout[1024], *sin, *sout;
int mode, lenin, lenout, ret, nline;
iconv_t c_pt;
if ((c_pt = iconv_open(encTo, encFrom)) == (iconv_t)-1)
{
printf("iconv_open false: %s ==> %s/n", encFrom, encTo);
return NULL;
}
iconv(c_pt, NULL, NULL, NULL, NULL);
lenin = strlen(in) + 1;
lenout = 1024;
sin = (char *)in;
sout = bufout;
ret = iconv(c_pt, &sin, (size_t *)&lenin, &sout, (size_t *)&lenout);
if (ret == -1)
{
return NULL;
}
iconv_close(c_pt);
return bufout;
}
int main(void)
{
xmlDocPtr doc = NULL;
xmlNodePtr cur = NULL;
doc = xmlParseFile("test.xml");
cur = xmlDocGetRootElement(doc);
printf("%s/n", (char *)xmlNodeGetContent(cur));
//printf("%s/n", Convert("utf-8", "gb2312", (char *)xmlNodeGetContent(cur)));
}
2) xmlFindCharEncodingHandler
使用数据类型:xmlCharEncodingHandlerPtr
/*******************************************
* compile: gcc -I/usr/include/libxml2/ -lxml2 convert.c
* usage: convert utf-8 string or null
* input: ./convert 测试
* output:
[wuqifu@localhost test]$ ./convert 测试
ISO-8859-1:虏芒脢脭
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>测试</root>
*******************************************/
#include <libxml/encoding.h>
/**
* function name: ConvertInput
* input:
@in: string in a given encoding
@encoding: the encoding used
* description: Converts @in into UTF-8 for processing with libxml2 APIs
* return: returns the converted UTF-8 string, or NULL in case of error.
**/
unsigned char* ConvertInput(const char *in, const char *encoding)
{
unsigned char *out;
int ret;
int size;
int out_size;
int temp;
xmlCharEncodingHandlerPtr handler;
if (in == 0)
return 0;
handler = xmlFindCharEncodingHandler(encoding);
if (!handler) {
printf("ConvertInput: no encoding handler found for '%s'/n",
encoding ? encoding : "");
return 0;
}
size = (int) strlen(in) + 1;
out_size = size * 2 - 1;
out = (unsigned char *) xmlMalloc((size_t) out_size);
if (out != 0) {
temp = size - 1;
ret = handler->input(out, &out_size, (const unsigned char *) in, &temp);
if ((ret < 0) || (temp - size + 1)) {
if (ret < 0) {
printf("ConvertInput: conversion wasn't successful./n");
} else {
printf
("ConvertInput: conversion wasn't successful. converted: %i octets./n",
temp);
}
xmlFree(out);
out = 0;
} else {
out = (unsigned char *) xmlRealloc(out, out_size + 1);
out[out_size] = 0; /*null terminating out */
}
} else {
printf("ConvertInput: no mem/n");
}
return out;
}
int main(int argc, char **argv)
{
unsigned char *content, *out;
xmlDocPtr doc;
xmlNodePtr rootnode;
char *encoding = "ISO-8859-1"; //utf-8, ISO-8859-1
if (argc <= 1) {
printf("Usage: %s content/n", argv[0]);
return(0);
}
content = argv[1];
out = ConvertInput(content, encoding);
printf( "%s:%s/n", encoding, out );
doc = xmlNewDoc ("1.0");
rootnode = xmlNewDocNode(doc, NULL, (const xmlChar*)"root", out);
xmlDocSetRootElement(doc, rootnode);
xmlSaveFormatFileEnc("-", doc, encoding, 1);
return (1);
}
使用简介
数据类型:
xmlChar 替代char,使用UTF-8编码的一字节字符串。如果你的数据使用其它编码,它必须被转换到UTF-8才能使用libxml的函数。
XmlDoc 包含由解析文档建立的树结构,xmlDocPtr是指向这个结构的指针。
xmlNodePtr and xmlNode 包含单一结点的结构
xmlNodePtr是指向这个结构的指针,它被用于遍历文档树。
优点:1. 安装、使用比较简单,容易入门;2. 支持的编码格式较多,能很好的解决中文问题(使用一个很简单的编码转换函数);3. 支持Xpath解析(这点对于任意定位xml文档中的节点还是很有用的哦);4.支持Well-formed 和valid验证,具体而言支持DTD验证,Schema验证功能正在完善中(目前多数解析器都还不完全支持shema验证功能);5. 支持目前通用的Dom、Sax方式解析等等。
不足:1. 指针太多,使用不当时就会出现错误,在Linux系统中表现为常见的段错误,同样管理不当易造成内存泄漏;2.个人认为内面有些函数的功能设计的不是很好(比如获取Xpath函数,它不获取节点属性,这样子有些情况会定位不准)。
在学习libxml2中,最好的学习手册就是由官方开发者提供的开发手册就是libxml2-devel-2.6.19,rpm –q –d libxml2获得文档路径,就是它了。
关于xml
开始研究 LibXML2 库之前,让我们先来巩固一下 XML 的相关基础。XML 是一种基于文本的格式,它可用来创建能够通过各种语言和平台访问的结构化数据。它包括一系列类似 HTML 的标记,并以树型结构来对这些标记进行排列。
例如,可参见清单 1 中介绍的简单文档。这是配置文件部分中研究的配置文件示例的简化版本。为了更清楚地显示 XML 的一般概念,所以对其进行了简化。
清单 1. 一个简单的 XML 文件
<?xml version="1.0" encoding="UTF-8"?>
<files>
<owner>root</owner>
<action>delete</action>
<age units="days">10</age>
</files>
清单 1 中的第一行是 XML 声明,它告诉负责处理 XML 的应用程序,即解析器,将要处理的 XML 的版本。大部分的文件使用版本 1.0 编写,但也有少量的版本 1.1 的文件。它还定义了所使用的编码。大部分文件使用 UTF-8,但是,XML 设计用来集成各种语言中的数据,包括那些不使用英语字母的语言。
接下来出现的是元素。一个元素以开始标记开始(如 <files>),并以结束标记结束(如 </files>),其中使用斜线 (/) 来区别于开始标记。
元素是
Node
的一种类型。XML 文档对象模型 (DOM) 定义了几种不同的Nodes
类型,包括Elements
(如files
或者age
)、Attributes
(如units
)和 Text(如root
或者10
)。元素可以具有子节点。例如,age 元素有一个子元素,即文本节点10
。而 files 元素有七个子元素。其中三个很明显。它们分别是三个子元素:owner
、action
和age
。其他四个分别是元素前后的空白文本符号。XML 解析器可以利用这种父子结构来遍历文档,甚至修改文档的结构或内容。LibXML2 是这样的解析器中的其中一种,并且文中的示例应用程序正是使用这种结构来实现该目的。对于各种不同的环境,有许多不同的解析器和库。LibXML2 是用于 UNIX 环境的解析器和库中最好的一种,并且经过扩展,它提供了对几种脚本语言的支持,如 Perl 和 Python。
1 tree
/*******************************************
* compile: gcc -I/usr/include/libxml2/ -lxml2 tree1.c
* usage: create a xml tree
*
*******************************************/
#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
int main(int argc, char **argv)
{
xmlDocPtr doc = NULL; /* document pointer */
xmlNodePtr root_node = NULL, node = NULL, node1 = NULL; /* node pointers */
//Creates a new document, a node and set it as a root node
doc = xmlNewDoc(BAD_CAST "1.0");
root_node = xmlNewNode(NULL, BAD_CAST "root");
xmlDocSetRootElement(doc, root_node);
//creates a new node, which is "attached" as child node of root_node node.
xmlNewChild(root_node, NULL, BAD_CAST "node1",BAD_CAST "content of node1");
// xmlNewProp() creates attributes, which is "attached" to an node.
node=xmlNewChild(root_node, NULL, BAD_CAST "node3", BAD_CAST"node has attributes");
xmlNewProp(node, BAD_CAST "attribute", BAD_CAST "yes");
//Here goes another way to create nodes.
node = xmlNewNode(NULL, BAD_CAST "node4");
node1 = xmlNewText(BAD_CAST"other way to create content");
xmlAddChild(node, node1);
xmlAddChild(root_node, node);
//Dumping document to stdio or file
xmlSaveFormatFileEnc(argc > 1 ? argv[1] : "-", doc, "UTF-8", 1);
/*free the document */
xmlFreeDoc(doc);
xmlCleanupParser();
xmlMemoryDump(); //debug memory for regression tests
return(0);
}
生成的xml:
[denny@localhost xml]$ gcc -I/usr/include/libxml2/ -lxml2 tree1.c
[denny@localhost xml]$ ./a.out
<?xml version="1.0" encoding="UTF-8"?>
<root>
<node1>content of node1</node1>
<node3 attribute="yes">node has attributes</node3>
<node4>other way to create content</node4>
</root>
执行序列:
1 声明指针:文档指针(xmlDocPtr),结点指针(xmlNodePtr);
2 生成文档doc:xmlNewDoc
3 生成根结点root_node: xmlNewDocNode ,xmlNewNode
4 文档与根结点捆绑: xmlDocSetRootElement
5 结点操作
1)创建子结点:xmlNewChild或xmlNewNode
2)设置结点属性:xmlNewProp
3)设置结点值:xmlNewText,xmlNewChild, xmlAddChild
6 释放内存:xmlFreeDoc,xmlMemoryDump
7 lib的载入退出: LIBXML_TEST_VERSION , xmlCleanupParser
2 parse
对于应用程序来说,读取 XML 文件的第一步是加载该数据并将其解析为一个
Document
对象。在此基础上,可以对 DOM 树进行遍历以获取特定的节点。/*******************************************
* compile: gcc -I/usr/include/libxml2/ -lxml2 tree1.c
* usage: tree2 filename_or_URL
*
*******************************************/
#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#ifdef LIBXML_TREE_ENABLED
static void
print_element_names(xmlNode * a_node)
{
xmlNode *cur_node = NULL;
for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
if (cur_node->type == XML_ELEMENT_NODE) {
printf("node type: Element, name: %s/n", cur_node->name);
}
print_element_names(cur_node->children);
}
}
/**
* Simple example to parse a file called "file.xml",
* walk down the DOM, and print the name of the
* xml elements nodes.
*/
int
main(int argc, char **argv)
{
xmlDoc *doc = NULL;
xmlNode *root_element = NULL;
if (argc != 2)
return(1);
//LIBXML_TEST_VERSION
/*parse the file and get the DOM */
doc = xmlReadFile(argv[1], NULL, 0);
if (doc == NULL) {
printf("error: could not parse file %s/n", argv[1]);
}
/*Get the root element node */
root_element = xmlDocGetRootElement(doc);
print_element_names(root_element);
/*free the document */
xmlFreeDoc(doc);
//xmlCleanupParser();
return 0;
}
#else
int main(void) {
fprintf(stderr, "Tree support not compiled in/n");
exit(1);
}
#endif
执行序列:
1 声明指针:文档指针(xmlDocPtr),结点指针(xmlNodePtr);
2 得到文档doc: xmlReadFile
3 得到根结点root_node:xmlDocGetRootElement
4 结点操作:
1)获得到结点值:xmlNodeGetContent(对应于xmlFree)
2)遍历:
指向下一个结点:xmlNodePtr ->children
结点值:xmlNodePtr->name,
结点内遍历:xmlNodePtr->next
5 释放内存:xmlFreeDoc,xmlFree
- using libxml2
- Using Libxml2
- using libxml2连载(1 中文支持)
- libxml2
- libxml2
- libxml2
- libxml2
- libxml2
- libxml2
- libxml2
- Libxml2
- libxml2
- libxml2
- Using libxml2 to get value of specific key
- using libxml2连载(2 使用简介与xml tree的生成解析)
- using libxml2连载(2 使用简介与xml tree的生成解析)
- Libxml2使用指南
- Libxml2使用指南
- 人生心态很重要
- 世界上最经典的语言(转载)
- 使用extern的问题,一个或多个多重定义的问题的解决
- ASP.Net Ajax 1.0正式版中存在的问题:第一次可以验证,但随后就不可以了
- 整数划分的问题
- using libxml2
- Asp.net 2.0 用 FileUpload 控件实现多文件上传 用户控件(示例代码下载)
- 10位表现最差企业家
- 读"南漂一族 挣百万 回老家"有感
- 关于一些学习php的总结
- Likelihood ratios for tests with more than two possible results
- 讨厌google 的新变化
- Beginning Transact-SQL With SQL Server 2000 and 2005 by Paul Turley
- 一些色彩方面的知识