前言:

  最近在开发的过程中,有个需求是对xml进行格式转化,从一种格式转化到另外一种格式.因此,就需要读取xml进行处理.原本打算写成工具在linux下运行,不过后来考虑到和系统结合,最后也就使用了前台js转了.反正都是读取xml,什么技术转不都是一样的么?

  不过刚开始还是对要使用的技术做了一定的探究.c++要读取xml有很多种方式.比较又名的有:

  rapidXML(这个是网上介绍的,没用过)

  Xerces-C++ XML Parser: 通常来说,读取XML的方法都是将整个文本进行读取,然后构建成DOM Tree,之后进行遍历等操作.这个Parser除了支持构建DOM Tree的方式之外,还支持类似于回调函数的方式进行处理(SAX,SAX2).在读到相应的节点然后调用函数进行处理.DOM Tree的方式好处是简单,操作很方便,但是劣势也是很明显:需要把整个XML读进之后才能做处理.如果XML很大,那内存就支撑不住 了.SAX,SAX2的作用就在此.其可以支持很大的XML,因为其是相当于事件式的处理方式,不需要构建DOM Tree.不过就是比较麻烦.

  TinyXML: 这个就是接下来要介绍的库了.取名Tiny,意在编写一个轻量级的处理基本XML的工具.因此,其支持的特性有限.下面列出了其不支持的功能:

  TinyXML doesn't parse or use DTDs (Document Type Definitions) or XSLs (eXtensible Stylesheet Language.)

                                                           -------------------官方说明文档

  其给出的理由也很明确:

  1. 支持这两个特性使得库更为庞大

  2. 使用更为复杂

  3. 学习曲线更曲折

  需要使用这些特性的可以考虑上面的xerces-C++ XML Parser.很强大.当然也复杂得多

TinyXml使用:

  前言说的已经够多了,咱们就不废话了,直接讲解tinyXml的使用方法.

安装:

    TinyXml的安装方法并不复杂,或者说没有安装这个步骤.

    1. 下载tinyXml ,下载tinyxml_2_6_2.zip

    2. 解压unzip tinyxml_2_6_2.zip.(windows就直接解压就可以了)

    

    对于有vs的朋友来说,直接打开tinyxml.sln就可以了.对于linux用户来说,则需要拷贝上面全出来的6个文件.

    PS.顺带的,我觉得可以把它的Makefile也拷出来.写得非常不错.可以参考参考.

  使用:

    tinyxml的使用方法很简单,只需要把拷出来的文件放在自己编写的目录下面,引用tinyxml.h,tinystr.h即可.

    简单示例代码:

    

 1 #include "tinyxml.h"
2 #include "tinystr.h"
3 #include <iostream>
4
5 using namespace std;
6 int main(int argc, char *argv[])
7 {
8 if(argc != 2)
9 {
10 cout << "usage: "<<argv[0] << " xmlfile" << endl;
11 return 1;
12 }
13 TiXmlDocument doc(argv[1]);
14 bool loadOk = doc.LoadFile();
15 if (!loadOk)
16 {
17 cout << "could load:" << doc.ErrorDesc() << endl;
18 }
19 TiXmlPrinter printer;//提供的工具类,目的是将xml的数据按格式输出
20 doc.Accept(&printer);
21 cout << printer.CStr() << endl;//输出
22
23 TiXmlElement*node = doc.FirstChildElement();//获取第一个element节点
24 cout << node->Value() << endl;//输出节点的值
25 string t;
26 node->QueryValueAttribute("type", &t);//获取节点属性
27 cout << t << endl;
28
29 doc.FirstChild()->NextSibling()->ToElement()->QueryStringAttribute("type", &t);//获取第二个子节点的数据
30 cout << "2:" << t << endl;
31
32 //使用遍历的方式进行处理
33 TiXmlNode* child = NULL;
34 TiXmlElement* element = NULL;
35 TiXmlAttribute *attr = NULL;
36 int ct;
37 while(child = doc.FirstChild()->IterateChildren(child))
38 {
39 cout << child->ValueStr() << "\t";
40 ct = child->Type();
41 cout << ct << "\t";
42 //根据不同的节点类型做相应处理
43 switch(ct)
44 {
45 case TiXmlNode::TINYXML_TEXT:
46 break;
47 case TiXmlNode::TINYXML_ELEMENT:
48 element = child->ToElement();
49 attr = element->FirstAttribute();
50 while(attr)
51 {
52 cout << attr->NameTStr() << "=" << attr->ValueStr() << '\t';
53 attr = attr->Next();
54 }
55 break;
56 }
57 }
58
59 return 0;
60 }

编译命令:

g++ -c tinyxmlparser.cpp -DTIXML_USE_STL
g++ -c tinyxmlerror.cpp -DTIXML_USE_STL
g++ -c tinystr.cpp -DTIXML_USE_STL
g++ -c tinyxml.cpp -DTIXML_USE_STL
g++ -c xmltest.cpp -DTIXML_USE_STL
g++ -o xmltest xmltest.o tinyxmlparser.o tinyxmlerror.o tinystr.o tinyxml.o

或者大家可以参考那个Makefile改改.

xml文件:

<xml>
<tag1 type='1'/>
<tag2 type='2'/>
</xml>

运行结果:

<xml>
<tag1 type="1" />
<tag2 type="2" />
</xml> xml 1:
tag1 1 type=1 tag2 1 type=2

   没打回车显得比较混乱,将就这看看.

详细解释:

    这部分仅仅是我的理解,可能有错.有错的话还请告知我下.

    tinyxml按照xml的规定,将所有结点做了区分.我们也可以看到类库中有:

    TiXmlDocument:文档中的根

    TiXmlNode: node为文档中所有结点的父类型.其可以转化为其他的结点类型.

    TiXmlElement: element结点.即我们平常所使用的,具有属性,tagName的结点.

    TiXmlComment: 注释

    TiXmlText: 文字结点.

    TiXmlDeclaration: xml的声明(?xml version="1.0" standalone="yes"?>)

    TiXmlUnknown: 任何tinyXml不认的结点都将归结为unknown,在重新写回文件时,按照原样输出.

    一般我们的操作仅仅在于,取tagName,获取属性,获取文字,迭代.这里就讲下这些操作.

    tagName: 对于element来说,可以使用element->Value()或者element->ValueStr();//两者区别仅仅在于返回值不同,后者返回string.

对于Value()函数来说,文档上也解释了,对于不同的结点,返回值不同.

		Document:	filename of the xml file
Element: name of the element
Comment: the comment text
Unknown: the tag contents
Text: the text string

    获取属性:获取属性有多种方式.最简单的是采用const char* Attrubute(const char *),或者采用QueryValueAttribute (const std::string &name, T *outValue) const.还有获取相应类型,如Int,double等的函数.可以自己查看手册.有时候需要遍历属性时,可以这么写

TiXmlAttribute *attr = NULL;
attr = element->FirstAttribute();
while(attr)
{
cout << attr->NameTStr() << "=" << attr->ValueStr();
attr = attr->Next();
}

    获取文字:element->GetText();

    迭代:

TiXmlNode *child = NULL;
while(child = parent->IterateChildren(child))
{
cout << child->ValueStr() << endl;
}

总结:

  对于TinyXml的介绍大致到这.还有很多细节还没叙述,不过可以看看文档,下的源码包里头就有doc,很方便,讲的也很详细.

有什么问题可以随时讨论.欢迎留言哈.

最新文章

  1. html css javascript 加载的顺序
  2. 高频sql语句汇总。不断更新。。
  3. 对hashmap与hashcode()、equals()的理解
  4. Python开发入门与实战11-单元测试
  5. Mysql在windows下和linux下对表名大小写默认要求的一个细节
  6. ios检查版本更新
  7. YII 数据库相关操作
  8. springMVC导出word模板
  9. git回退到某个历史版本
  10. 关于Windows系统不会变慢的设想
  11. Android开发过程中的坑及解决方法收录(五)
  12. Luogu 1314 【NOIP2011】聪明的质检员 (二分)
  13. Linux学习笔记:系统目录结构
  14. VisualStudio使用技巧及快捷键
  15. Selenium笔记:PO模型
  16. 使用multiprocessing中的常见问题
  17. 关于Unity中的NGUI和UGUI
  18. Oracle中查询主键、外键、sequence、表基本信息等
  19. (转)mysql 备份与恢复mysqlhotcopy
  20. RDD 算子补充

热门文章

  1. Activity设置style透明后与SurfaceView合用引发的无形命案
  2. 在JDK 6和JDK 7的substring()方法的区别?
  3. 关于Python有用的snippets
  4. Java for LeetCode 099 Recover Binary Search Tree
  5. linux下tar.xz结尾文件的解压方法
  6. LeetCode:奇偶链表【328】
  7. springmvc fastjson 反序列化时间格式化
  8. MVC+Ext.net零基础学习记录(三)
  9. Hadoop- Hadoop环境搭建
  10. 「洛谷 P1801」黑匣子