linux c xml 读写
2010-05-11 15:16:33| 分类: xml | 标签: |字号大中小 订阅
在网络上似乎找不到太多的资料。
我觉得 http://www.xmlsoft.org/tutorial/index.html
的教程不错。给大家介绍一下。。是英文,不过很简单。相信做编程的人不会看不懂。。
给出国内的一资料,写得也很不错。(程序 我测试过了)
使用简介
数据类型:
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