开发者社区> zting科技> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

自己写的简单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,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
大话XML解析
之前我写过一篇关于xml解析的文章:http://blog.csdn.net/sdksdk0/article/details/50749326。今天这篇文章主要是进一步加深对xml基础的理解了使用,毕竟基础是很重要的嘛!写的应该会更注重细节的内容。主要内容有xml语法、DOM解析、SAX解析、Xpath,schema约束。 一、xml语法 标签 有开始标签和结束标
1187 0
Dom4解析xml
 dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它.        对主流的Java XML API进行的性能、功能和易用性的评测,dom4j无论在那个方面都是非常出色的。如今你可以
1147 0
解析xml文件的几种技术
1、 解析xml的几种技术         1.dom4j         2.sax         3.jaxb         4.jdom         5.dom 1.dom4j              dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和
1494 0
C# 写XML文件
/// x /// 修改xml文件 /// /// private void ModifyXml(DataTable dt) {   XmlDataDocument doc = new XmlDataDocument()...
664 0
DOM解析XML文件
首先是定义一个XML文件,文件名为student.xml,代码如下:       05205020227    YJ    女        05205020228    YKF    男  ...
594 0
+关注
3549
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载