简单的XML读取器
- XML 指可扩展标记语言(EXtensible Markup Language)
(有个很明显的槽点),是一种主要设计用来数据传输存储的语言。
有关语法规则我是参考了这个链接。
http://www.w3school.com.cn/xml/xml_syntax.asp
看 gcc4 的时候觉得数据驱动编程很酷,于是顺带觉得xml很酷,正好暑假闲就写了个xml读取器看看,鼓捣了几天,弄好了大致上的功能,这里所说大致上,是能够满足检查语法错误并给出错误信息到标准输出设备(不保证报错信息绝对有用)。如果满足语法规则,就能正确读取xml所描述的数据并保存成一颗元素树。
以上这些是初期的目标,大体上实现了,接下来再说说另外想要实现的
1.实现一个接口类,提供能使用户方便使用的功能足够强大的接口去访问读取出来的 xml 树。比如查找所有 name 为 "title" 的标签
2.正确处理声明,因为没有处理声明,所以中文什么的就别想了,话说bom我也没处理。。。
3.正确处理注释(其实我觉得像现在这样跳过忽略就挺好的)
4 .正确处理 DOCTYPE,不得不说,这个的语法我觉得比xml的要复杂, xml 这个算良心级的简单易解析的语法我都写出了那又臭又长的代码,完成这个目标的工作量让我敬而远之,感觉不太可能会去写了。
说说写的过程的一些感受, xml 的设计者良心大大地好啊,因为 tag 的对称 close 的要求,可以很方便地用一个堆栈去完成读取建树过程,错误检查难度也下降很多
各种语法上看似苛刻的规定虽然麻烦了它的编写(真的会有人手写这个嘛,怎么想都是程序生成靠谱啊。。),但是却很有利于去读取它,可以经常一言不合就报错,哈哈,写起来轻松不少。另外就是因为是用 c++ 写它的,所以本能地就用了面对对象的写法,后来发现不对,一大半代码是由 buildTree 组成的,有一种以前没学函数写 c 语言的感觉,后来代码就变成了这样大而不当的样子(快200行的成员函数你怕不怕!)
https://github.com/Dadio44/TxmlReader/blob/master/TxmlReader/TxmlReader.cpp
后来想了想,这种算法比较复杂的代码(又设计到很多局部变量),干脆把解析过程放在非成员函数,把大函数切割成许多小函数,可读性,可修改性,可重用性都会好很多,所以说写代码时千万不能偷懒,觉得这里只是需要怎么样怎么样,这样就好了,结果经验表明一次把代码写好是不可能的,以后总要这样那样,随时做好代码会变得面目全非的准备比较好,切莫图一时之快。这个代码需要好好地 reconstructe 。但是,以上的目标都要建立在我闲下来又心情好的情况下,比较仔细想想老坑还是有很多没填的。。。
最后这个是完整代码
https://github.com/Dadio44/TxmlReader/tree/master/TxmlReader
7月21日
增加了对 utf-8(无BOM)的支持,本来还想试着支持下其他编码的,但是太麻烦还是算了,反正这个编码的使用率对其他的编码是碾压而且又很好兼容 asiic (感觉就是因为这点所以才流行 )所以,别的编码不要想了,在在 windows 上运行的话,需要把 utf-8 转 gbk (中文)才能在控制台看懂输出(其实也可以通过换控制台编码来解决)。所以用了宏来区分操作系统(仅linux和windows有测试过)
7月24日
知道了 DOM 这东西就开始着手写对 XML 的编程接口,鼓捣了两天,各种疯狂查询 STL,早知道就把 C++ Primer 带回家,现在这些通过了简单的测试。
XmlTreeHandle 用来当作接口类的,大部分只是对 XmlTree 的接口做了内联调用而已。除了 addChild() 这个函数 ,因为在成员函数中,无法把当前调用 XmlTree
相关的 shared_ptr 传给当前的 XmlTree 的 _parent (类型是 weak_ptr)。为了能够以实现对一个 XmlTree 添加子树,子树能自动修改父节点,就需要这个接口类的
存在,没错,只为了一个函数就给它加了个类,才怪,只是因为这样能更好地封装,鬼知道明天会不会发现什么新bug,或者想加什么新功能。
后续可能会加入声明的读取。这样就能把读出来的 XML 树给修改(或者不)然后输出保存成新的 XML 文档。当然这一切都只是 可能,最后顺便一提,现在带 BOM 的 UTF-8 也支持了。