using libxml2连载(2 使用简介与xml tree的生成解析)

使用简介
数据类型:
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.19rpm –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
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值