您的当前位置:首页正文

二十八、Qt数据库(八)XML(一)

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

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

在这里我们可以看到所有相关的类,它们主要是服务于两种操作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 )。

下面我们更改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” 。然后我们利用记事本打开该文件,并将上面的XML文档的信息写入其中,不要写注释信息,然后保存。

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

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

qDebug() << qPrintable(firstNode.nodeName()) //输出XML说明 << qPrintable(firstNode.nodeValue()); 这里利用了qPrintable()函数。 效果如下:

下面我们在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()循环来实现对所有子元素的遍历。运行结果如下:

下面我们更改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; iQDomNode node = list.at(i); if(node.isElement())

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

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

QDomElement e = n.toElement();

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

分类:Qt系列教程 作者: yafeilinux 日期: 五月 4th, 2010. 499 views Tags: creator, dom, qt, xml, yafeilinux, 教程, 数据库

6 条评论 在 “二十八、Qt数据库(八)XML(一)”

1. yafeilinux 说:

2010年05月26日于9:22 下午 是当时漏写了。哈,太大意了,没发现!

2. rxpeng 说:

2010年05月26日于9:06 下午

在你的XML文档中,第三行“//library元素的第一个子元素,“id”是其属性”中的“id”在哪?我想是不是应该是“book”啊?

3. ding404 说:

2010年05月26日于10:53 上午 学习完毕,谢谢楼主n(O_O)n

4. liyayao 说:

2010年05月8日于2:01 下午 原来是my.xml标点的问题,谢谢啦

5. yafeilinux 说: 2010年05月7日于2:41 下午

那是因为你的程序运行处错了。你把能删的都删掉,看是哪里出错了。

因篇幅问题不能全部显示,请点此查看更多更全内容