自己写的简单xml解析器

简介:

已经自我放逐好几年了.打算去上班得了.在最后的自由日子里,做点有意义的事吧...

先来下载地址
http://www.kuaipan.cn/file/id_12470514853353274.htm

已经在很多正式,非正式的场合用过了.干脆开源得了.BSD授权.
代码比较久远,最后一次修改也在4~5年前了.写的比较BT,只有gcc/vc/icl能编译...
不过性能和易用性还是不错的.之前我测试过的,只有几个in place的xml解析器稍微比我的快一点点.
下面是示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// xml-test.cpp
#include <stdio.h>
#include "xml.h"
 
// 自定义FILE*输出策略
class  cfile_writer {
     FILE  *_fp;
     cfile_writer &operator = (  const  cfile_writer& );
     cfile_writer(  const  cfile_writer& );
public :
     cfile_writer(  FILE  *fp ) : _fp(fp) {
         fputs "-----------------\n" , _fp );
     }
     ~cfile_writer() {
         fputs "\n" , _fp );
     }
     // 策略不用预分配空间
     // 如果为1, 在输出前会计算要占空间大小, 并调用resize接口进行预分配.
     static  const  int  need_pre_allocate = 0;
     // 预分配接口
     bool  resize(  size_t  size )  const  return  true ; }
     // 输出一个字符
     void  write(  char  value )  const   {
         fputc ( value, _fp );
     }
     // 输出一个字符串, 长度由size指定
     void  write(  const  char  *value,  size_t  size )  const   {
         fwrite ( value, 1, size, _fp );
     }
};
 
int  main() {
     using  namespace  cpp::utils;
     const  char  xml_string[] =  "<root attr=\"root attr\"><node prop=\"234\"/>text content<!-- comment --></root>" ;
     xml x;
 
     // 解析xml_string, 用不同的reader策略可以从不同的源中读数据
     // 也可以自定义读策略, 以适应不同的需求
     // 解析成功返回true.如果只有部分解析成功时虽然返回false,但已经解析成功的内容仍然可用
     // 如果宏XML_WITH_PARSE_STATUS设置为1(默认为0).可以从x.info()中得到解析器停止的位置,方便调试.但会降低解析器性能.
     x.parse( xml_reader( xml_string ) );
 
     xml x2;
     x2.push_back( xml::tag( "root-x2" ) );    // 直接向空xml对象中添加标签
     x2( "root-x2" ).push_back( xml::text( "text value" ) );
     x2.write( cfile_writer( stderr ) );
     
     // 输出/root/node[prop]的值
     // ()运算符为标签查找,返回指定名称的第一个标签.[]运算符为属性查找,返回指定名称的属性.
     printf "/root/node[prop] = [%s]\n" , x( "root" )( "node" )[ "prop" ].value().c_str() );
     // 这里使用了null object模式,所以无需检查每一步的返回结果,不会因为访问非法节点而产生异常.简化使用
     printf "null object test:[%s]\n" , x( "roxxot" )( "noeede" )[ "prop" ].value().c_str() );
 
     // 把root标签转成其迭代器(&运算符)
     xml::tag_iterator root_tag = &x( "root" );
     
     // 迭代所有子节点
     for ( xml::node_iterator node = x.root()->begin(); node != x.root()->end(); ++node ) {
         // xml::node_iterator为通用节点迭代器, 可以指向任何类型的节点.
         // 并可以转型成任意的其它迭代器. 但如果指向的节点类型和目标迭代器类型不符, 则会自动指向下一个合法的节点
         // 比如: <abc/><!--comment-->
         //       这里有两个节点,一个abc标签,一个注释.
         //       如果有当前node迭代器指向abc标签.
         //            把node转成xml::tag_iterator类型时,则指向的节点不变.
         //            如果转成xml::comment_iterator时则会指向后面的注释.
         //            如果转成其它不存在类型的节点,则会指向容器的末尾.
         printf "node type: %d\t" , node->type );
         switch ( node->type ) {
         case  xml::_TYPE_TAG:
             printf "tag name:%s\n" , xml::tag_iterator(node)->name().c_str() );
             break ;
         case  xml::_TYPE_COMMENT:
             printf "comment:%s\n" , xml::comment_iterator(node)->text().c_str() );
             break ;
         case  xml::_TYPE_TEXT:
             printf "text:%s\n" , xml::text_iterator(node)->text().c_str() );
             break ;
         case  xml::_TYPE_ATTRIBUTE:
             printf "attribute:%s=%s\n" , xml::attribute_iterator(node)->name().c_str(), xml::attribute_iterator(node)->value().c_str() );
             break ;
         default :
             printf "unknown type\n"  );
             break ;
         }
     };
 
     // 迭代所有子标签
     for ( xml::tag_iterator tag = x.root()->begin(); tag != x.root()->end(); ++tag ) {
         // 专用类型的迭代器只能遍历此类型的节点
         printf "tag:%s\n" , tag->name().c_str() );
     }
 
     // 在/root/node下添加abc标签, 并保存指向标签的迭代器
     xml::tag_iterator abc_tag = x( "root" )( "node" ).push_back( xml::tag(  "abc"  ) );
     // 用abc_tag迭代器向abc标签添加属性
     abc_tag->push_back( xml::attribute(  "tag-prop" "value abcdefg"  ) );
     // 在abc标签前插入注释
     abc_tag->parent().insert( abc_tag, xml::comment(  "tag-prop comment"  ) );
     // 把xml_string解析出来,并将结果放到abc_tag所指向的标签里
     abc_tag->parse( xml_reader( xml_string ) );
     // 深拷贝x2对象中的根节点到abc标签中,实现跨xml对象进行节点复制
     abc_tag->push_front_copy( x2.root() );
     // 输出abc_tag指向的标签, 第二个参数true表示只输出内容标签的内容,不包含标签本身及属性
     abc_tag->write( cfile_writer( stdout ),  true  );
     // 删除第一个子节点
     abc_tag->erase( abc_tag->begin() );
     abc_tag->write( cfile_writer( stdout ),  true  );
     // 不能直接删除孙节点
     x.erase( xml::tag_iterator(abc_tag->begin()) );    // 转型成xml::tag_iterator是因为abc的第一个节点是属性.删除不直观.用标记会明显点
     abc_tag->write( cfile_writer( stdout ) );    // 没有删掉
     // 递归删除可以成功
     x.recursion_erase( xml::tag_iterator(abc_tag->begin()) );
     abc_tag->write( cfile_writer( stdout ) );    // 已经删除成功
     return  0;
}

只支持基本语法,很多东西不支持.比如:CDATA不支持,自定义转意也不支持...
用来做配置文件还是不错.

原文地址


本文转自Work Hard Work Smart博客园博客,原文链接:http://www.cnblogs.com/linlf03/archive/2013/01/03/2843273.html,如需转载请自行联系原作者

目录
相关文章
|
11天前
|
XML JavaScript 前端开发
xml文件使用及解析
xml文件使用及解析
|
1月前
|
XML 前端开发 数据格式
请描述如何使用`BeautifulSoup`或其他类似的库来解析 HTML 或 XML 数据。
【2月更文挑战第22天】【2月更文挑战第67篇】请描述如何使用`BeautifulSoup`或其他类似的库来解析 HTML 或 XML 数据。
|
2月前
|
XML 机器学习/深度学习 JSON
在火狐浏览器调ajax获取json数据时,控制台提示“XML 解析错误:格式不佳”。
在火狐浏览器调ajax获取json数据时,控制台提示“XML 解析错误:格式不佳”。
29 0
在火狐浏览器调ajax获取json数据时,控制台提示“XML 解析错误:格式不佳”。
|
29天前
|
XML Java 数据格式
使用java解析XML文件的步骤
使用java解析XML文件的步骤
10 0
|
1月前
|
XML 存储 JavaScript
深入学习 XML 解析器及 DOM 操作技术
所有主要的浏览器都内置了一个XML解析器,用于访问和操作XML XML 解析器 在访问XML文档之前,必须将其加载到XML DOM对象中 所有现代浏览器都有一个内置的XML解析器,可以将文本转换为XML DOM对象
72 0
|
1月前
|
XML 安全 API
Python读写XML文件:深入解析与技术实现
Python读写XML文件:深入解析与技术实现
43 0
|
1月前
|
Java 应用服务中间件
解决tomcat启动报错:无法在web.xml或使用此应用程序部署的jar文件中解析绝对的url [http:java.sun.com/jsp/jstl/core]
解决tomcat启动报错:无法在web.xml或使用此应用程序部署的jar文件中解析绝对的url [http:java.sun.com/jsp/jstl/core]
111 1
|
1月前
|
XML JSON 数据格式
xml文档解析报错解决办法
xml文档解析报错解决办法
|
1月前
|
XML 数据格式
AXios接受XML格式的webservice并解析成数据格式
AXios接受XML格式的webservice并解析成数据格式
25 2
|
2月前
|
XML 存储 IDE
Java_XML解析精讲
Java_XML解析精讲
22 0

推荐镜像

更多