Chinaunix首页 | 论坛 | 博客
  • 博客访问: 281477
  • 博文数量: 59
  • 博客积分: 1346
  • 博客等级: 中尉
  • 技术积分: 461
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-06 17:17
文章分类

全部博文(59)

文章存档

2012年(9)

2011年(50)

分类: C/C++

2011-08-26 10:22:26

本文章原创于 转载请注明出处。

我们把XML放到数据库部分来讲,因为XML与数据库有着千丝万缕的联系,这里我们不再对XML进行过多的介绍,如果你还没有接触过它,可以在网上搜索一下关键字,其实对于我们下面讲述的内容,即便你不知道什么是XML,你也会很快掌握的。

在Qt中提供了QtXml模块实现了对XML数据的处理,我们在Qt帮助中输入关键字QtXml Module,可以看到该模块的类表。

1_39.jpg (97 KB)

在这里我们可以看到所有相关的类,它们主要是服务于两种操作XML文档的方法:DOM和SAX。Dom(Document Object Model,即文档对象模型)把XML文档转换成应用程序可以遍历的树形结构,这样便可以随机访问其中的节点。它的缺点是需要将整个XML文档读入内存,消耗内存较多。对于SAX我们放到后面再讲。

除了上面的两种方法外,Qt还提供了简单的QXmlStreamReader和QXmlStreamWriter对XML文档进行读写。

下面我们先介绍使用DOM的方式来操作XML文档。

下面是一个规范的XML文档:

  //XML说明

  //根元素

  //library元素的第一个子元素,“id”是其属性

Qt   //book元素的子元素,“Qt”是元素的文本

shiming   //book元素的子元素,title元素的兄弟元素

  //结束标记名

Linux

yafei

(我们为了讲述方便使用了//注释,其实XML文档中是没有这些注释的)

可以看到,一个规范的XML文档,是用XML说明开始的,主要由各元素组成。XML文档第一个元素就是根元素,XML文档必须有且只有一个根元素。元素是可以嵌套的。

下面我们就使用程序读出该文档中所有信息。

在Qt Creator中新建控制台工程Qt4 Console Application,工程名为xml01,在选择模块页选中QtXml(如果在这里没有添加,就需要在工程文件中手动添加QT += xml ;在新版本的Qt Creator中可能没有模块添加页,只能在对应的.pro文件中手动添加)。

下面我们更改main.cpp的内容如下:

#include

#include

int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

QDomDocument doc;   //新建QDomDocument类对象,它代表一个XML文档

QFile file(“my.xml”);   //建立指向“my.xml”文件的QFile对象

if (!file.open(QIODevice::ReadOnly)) return 0;  //以只读方式打开

if (!doc.setContent(&file)) { file.close(); return 0; }

//将文件内容读到doc中

file.close();

//关闭文件

QDomNode firstNode = doc.firstChild();  //获得doc的第一个节点,即XML说明

qDebug() << firstNode.nodeName()   //输出XML说明

<< firstNode.nodeValue();

return a.exec();

}

我们先运行一下程序。然后在工程文件夹的debug文件夹下单击鼠标右键,新建文本文档,改名为“my.xml”,这里一定要注意把原来的“.txt”后缀改为“.xml”(注:在新版的Qt Creator中可能需要将文件放在xml01-build-desktop文件夹中) 。然后我们利用记事本打开该文件,并将上面的XML文档的信息写入其中,不要写注释信息,然后保存。

2_13.jpg (221 KB)3_31.jpg (236 KB)4_1.jpg (94 KB)

再次运行程序,效果如下:

5_2.jpg (64 KB)

我们不愿意让输出信息出现双引号,可以更改程序代码:

qDebug() << qPrintable(firstNode.nodeName())   //输出XML说明

<< qPrintable(firstNode.nodeValue());

这里利用了qPrintable()函数。

效果如下:

6_2.jpg (63 KB)

下面我们在return a.exec();代码前继续添加代码:

QDomElement docElem = doc.documentElement();  //返回根元素

QDomNode n = docElem.firstChild();   //返回根节点的第一个子节点

while(!n.isNull())

{   //如果节点不为空

if (n.isElement())  //如果节点是元素

{

QDomElement e = n.toElement();  //将其转换为元素

qDebug() << qPrintable(e.tagName())   //返回元素标记

<< qPrintable(e.attribute(“id”));  //返回元素id属性的值

}

n = n.nextSibling();  //下一个兄弟节点

}

这样便能输出根元素及其子元素了。我们这里使用了firstChild()函数和nextSibling()函数,然后利用while()循环来实现对所有子元素的遍历。运行结果如下:

7_12.jpg (66 KB)

下面我们更改if()语句中的代码,用另一种方法遍历book元素的所有子元素。

if (n.isElement())  //如果节点是元素

{

QDomElement e = n.toElement();  //将其转换为元素

qDebug() << qPrintable(e.tagName())   //返回元素标记

<< qPrintable(e.attribute(“id”));  //返回元素id属性的值

QDomNodeList list = e.childNodes(); //获得元素e的所有子节点的列表

for(int i=0; i

{

QDomNode node = list.at(i);

if(node.isElement())

qDebug() << “   “<< qPrintable(node.toElement().tagName())

<

}

}

这里使用了childNodes()函数获得了元素所有子节点的列表,然后通过遍历这个列表实现了遍历其所有子元素。运行程序,效果如下:

8_17.jpg (74 KB)

小结:通过上面的例子,我们实现了对一个XML文档的读取。可以看到,在QDom中,是将整个XML文件读到内存中的doc对象中的。然后使用节点(QDomNode )操作doc对象,像XML说明,元素,属性,文本等等都被看做是节点,这样就使得操作XML文档变得很简单,我们只需通过转换函数将节点转换成相应的类型,如

QDomElement e = n.toElement();

在下一节我们将讲述XML文件的创建和写入。

 DOM.rar   

 

阅读(2309) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~