Dom(Document Object Model,即文档对象模型)把XML文档转换成应用程序可以遍历的树形结构,这样便可以随机访问其中的节点。它的缺点是需要将整个XML文档读入内存,消耗内存较多。
在Qt中使用QDomProcessingInstruction类来表示XML说明,元素对应QDomElement类,属性对应QDomAttr类,文本内容由QDomText类表示。所有的DOM节点,比如这里的说明、元素、属性和文本等,都使用QDomNode来表示,然后使用对应的isProcessingInstruction()、isElement()、isAttr()和isText()等函数来判断是否是该类型的元素,如果是,那么就可以使用toProcessingInstruction()、toElement()、toAttr()和toText()等函数转换为具体的节点类型。
1、新建Qt控制台应用。在.pro中添加:
QT += core xml
2、更改:
my.xml
<?xml version="1.0" encoding="UTF-8"?>
<library>
<book id="01">
<title>Qt</title>
<author>shiming</author>
</book>
<book id="02">
<title>Linux</title>
<author>yafei</author>
</book>
</library>
main.cpp
#include <QCoreApplication>
#include <QDomDocument>
#include <QFile>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QDomDocument doc; //新建立一个QDomDocument对象,表示一个xml文档
QFile file("my.xml");//建立指向my.xml文件的QFile对象.
/*
* 打开文件的3种方法:
* 1、file("my.xml")将文件添加到build-mydom-Desktop_Qt_5_8_0_MinGW_32bit-Debug目录下
* 2、QFile file("F:/share/injector-gui2/recordshistoryrecords.xml");绝对路径
* 3、QFile file(":/recordshistoryrecords.xml");资源文件
*/
if(!file.open(QIODevice::ReadOnly)) //以只读方式打开
{
qDebug() << "打开失败";
return 0;
}
QString errorStr;
int errorLine;
int errorCol;
//setContent是将指定的内容指定给QDomDocument解析,
//第一参数可以是QByteArray或者是文件名等
if(!doc.setContent(&file, true, &errorStr, &errorLine, &errorCol)){ //将文本内容读到doc中
qDebug() << errorStr << "line: " << errorLine << "col: " << errorCol; //如果出错,则会进入这里。errorStr得到的是出错说明,errorLine和errorCol则是出错的行和列
file.close(); //打开失败原因:<?xml version="1.0"<空格>encoding="UTF-8"?>, ?lia两边不能有空格
return 0;
}
file.close(); //关闭文件
//获取doc的第一个节点,即xml说明
QDomNode firstNode = doc.firstChild();
qDebug() << firstNode.nodeName()
<< firstNode.nodeValue(); //输出xml说明:有引号
qDebug() << qPrintable(firstNode.nodeName())
<< qPrintable(firstNode.nodeValue());
return a.exec();
}
#include <QCoreApplication>
#include <QDomDocument>
#include <QFile>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QDomDocument doc; //新建立一个QDomDocument对象,表示一个xml文档
QFile file("my.xml");//建立指向my.xml文件的QFile对象.
/*
* 打开文件的3种方法:
* 1、file("my.xml")将文件添加到build-mydom-Desktop_Qt_5_8_0_MinGW_32bit-Debug目录下
* 2、QFile file("F:/share/injector-gui2/recordshistoryrecords.xml");绝对路径
* 3、QFile file(":/recordshistoryrecords.xml");资源文件
*/
if(!file.open(QIODevice::ReadOnly)) //以只读方式打开
{
qDebug() << "打开失败";
return 0;
}
QString errorStr;
int errorLine;
int errorCol;
//setContent是将指定的内容指定给QDomDocument解析,
//第一参数可以是QByteArray或者是文件名等
if(!doc.setContent(&file, true, &errorStr, &errorLine, &errorCol)){ //将文本内容读到doc中
qDebug() << errorStr << "line: " << errorLine << "col: " << errorCol; //如果出错,则会进入这里。errorStr得到的是出错说明,errorLine和errorCol则是出错的行和列
file.close(); //打开失败原因:<?xml version="1.0"<空格>encoding="UTF-8"?>, ?lia两边不能有空格
return 0;
}
file.close(); //关闭文件
//获取doc的第一个节点,即xml说明
QDomNode firstNode = doc.firstChild(); //<?xml version="1.0" encoding="UTF-8"?>
qDebug() << qPrintable(firstNode.nodeName())
<< qPrintable(firstNode.nodeValue());
QDomElement docElem = doc.documentElement(); //library
qDebug() << qPrintable(docElem.nodeName())
<< qPrintable(docElem.nodeValue());
QDomNode fstNode = docElem.firstChild(); //返回根节点的第一个子节点
// qDebug() << qPrintable(fstNode.toElement().tagName()) //book, 元素标记
// << qPrintable(fstNode.toElement().attribute("id")); //01, 元素属性id的值
while(!fstNode.isNull()) //如果节点不为空, book
{
if (fstNode.isElement()) //如果节点是元素
{
QDomElement e = fstNode.toElement(); //将其转换为元素
qDebug() << qPrintable(e.tagName()) //返回元素标记 book
<< qPrintable(e.attribute("id")); //返回元素id属性的值
//获取元素book的所有子节点链表
QDomNodeList list = fstNode.childNodes();
for(int i = 0; i < list.size(); ++i) //遍历该链表
{
QDomNode node = list.at(i);
if(node.isElement())
qDebug() << " "<< qPrintable(node.toElement().tagName()) //返回元素标记
<< " "<< qPrintable(node.toElement().text());
}
}
fstNode = fstNode.nextSibling(); //下一个兄弟节点
}
return a.exec();
}