【Qt】DOM读取XML文档
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 開發(fā)環(huán)境
- 03. XML文檔示例
- 04. DOM讀取XML文檔內(nèi)容
- 05. 預(yù)留
- 06. 附錄
01. 概述
DOM(Document Object Model,文檔對象模型),是W3C的推薦標(biāo)準(zhǔn)。它提供了一個(gè)接口來訪問和改變一個(gè)XML文件的內(nèi)容和結(jié)構(gòu),可以將XML文檔表示為一個(gè)存儲(chǔ)在內(nèi)存中具有層次的樹視圖。文檔本身由QDomDocument對象來表示,而文檔樹中所有的DOM節(jié)點(diǎn)都是QDomNode類的子類。
在Qt中使用QDomProcessingInstruction類來表示XML說明。元素對應(yīng)QDomElement類。屬性對應(yīng)QDomAttr類。文本內(nèi)容由QDomText類表示。所有的DOM節(jié)點(diǎn),比如這里的說明、元素、屬性和文本等,都使用QDomNode來表示。
元素對應(yīng)QDomElement 類。元素可以包含屬性,用來描述元素的相關(guān)信息,屬性名和屬性值在元素的起始標(biāo)簽中給出。
屬性值必須在單引號(hào)或者雙引號(hào)中。屬性對應(yīng)QDomAttr 類。
元素中可以包含子元素,也可以只包含文本內(nèi)容,比如這里<first-name> Mary </first-name>中的Mary就是文本內(nèi)容,文本內(nèi)容由QDomText 類表示。
XML(ExtensibleMarkup Language,可擴(kuò)展標(biāo)記語言),是一種類似于HTML的標(biāo)記語言,但它的設(shè)計(jì)目的是用來傳輸數(shù)據(jù),而不是顯示數(shù)據(jù)。XML的標(biāo)簽沒有被預(yù)定義,用戶需要在使用時(shí)自行進(jìn)行定義。XML是W3C(萬維網(wǎng)聯(lián)盟)的推薦標(biāo)準(zhǔn)。相對于數(shù)據(jù)庫表格的二維表示,XML使用的樹形結(jié)構(gòu)更能表現(xiàn)出數(shù)據(jù)的包含關(guān)系,作為一種文本文件格式,XML簡單明了的特性使得它在信息存儲(chǔ)和描述領(lǐng)域非常流行。
? 在Qt中提供了Qt XML模塊來進(jìn)行XML文檔的處理,這里主要提供了兩種解析方法: DOM方法,可以進(jìn)行讀寫;SAX方法,可以進(jìn)行讀取。從Qt 5開始,Qt XML模塊不再進(jìn)行維護(hù),而是推薦使用Qt Core模塊中基于流的方法,分別使用QXmlStreamReader和QXmlStreamWriter進(jìn)行讀取和寫入。本文檔先來講解一下DOM的方法。要在項(xiàng)目中使用Qt XML模塊,需要在項(xiàng)目文件(.pro文件)中添加QT += xml一行代碼。
02. 開發(fā)環(huán)境
Windows系統(tǒng):Windows10
Qt版本:Qt5.15、Qt6
03. XML文檔示例
規(guī)范的XML文檔如下所示:
<?xml version="1.0"encoding="UTF-8"?> <library><book id="01"><title>Qt</title><author>LiMing</author></book><book id="02"><title>Linux</title><author>ZhengGang</author></book> </library>每個(gè)XML文檔都由XML說明(或者稱為XML序言)開始,它是對XML文檔處理的環(huán)境和要求的說明,比如這里的,其中xml version=“1.0”,表明使用的XML版本號(hào),這里字母是區(qū)分大小寫的;encoding=“UTF-8”是使用的編碼,指出文檔是使用何種字符集建立的,默認(rèn)值為Unicode編碼。XML文檔內(nèi)容由多個(gè)元素組成,一個(gè)元素由起始標(biāo)簽<標(biāo)簽名>和終止標(biāo)簽以及兩個(gè)標(biāo)簽之間的內(nèi)容組成,而文檔中第一個(gè)元素被稱為根元素,比如這里的,XML文檔必須有且只有一個(gè)根元素。元素的名稱是區(qū)分大小寫的,元素還可以嵌套,比如這里的library、book、title和author等都是元素。元素可以包含屬性,用來描述元素的相關(guān)信息,屬性名和屬性值在元素的起始標(biāo)簽中給出,格式為<元素名 屬性名=“屬性值”>,如,屬性值必須在單引號(hào)或者雙引號(hào)中。在元素中可以包含子元素,也可以只包含文本內(nèi)容,比如這里的中的Qt就是文本內(nèi)容。
04. DOM讀取XML文檔內(nèi)容
Dom(Document Object Model,即文檔對象模型)把XML文檔轉(zhuǎn)換成應(yīng)用程序可以遍歷的樹形結(jié)構(gòu),這樣便可以隨機(jī)訪問其中的節(jié)點(diǎn)。它的缺點(diǎn)是需要將整個(gè)XML文檔讀入內(nèi)存,消耗內(nèi)存較多。
在Qt中使用QDomProcessingInstruction類來表示XML說明,元素對應(yīng)QDomElement類,屬性對應(yīng)QDomAttr類,文本內(nèi)容由QDomText類表示。所有的DOM節(jié)點(diǎn),比如這里的說明、元素、屬性和文本等,都使用QDomNode來表示,然后使用對應(yīng)的isProcessingInstruction()、isElement()、isAttr()和isText()等函數(shù)來判斷是否是該類型的元素,如果是,那么就可以使用toProcessingInstruction()、toElement()、toAttr()和toText()等函數(shù)轉(zhuǎn)換為具體的節(jié)點(diǎn)類型。
4.1 新建Qt控制臺(tái)應(yīng)用QtConsole Application,項(xiàng)目名稱為16XML。
4.2 在16XML.pro配置文件中添加下一行
QT += xml4.3 main.cpp內(nèi)容如下
int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);//新建QDomDocument類對象 代表一個(gè)XML文檔QDomDocument doc;//創(chuàng)建test.xml文件QFile file("../test.xml");//以只讀方式打開該文件bool ret = file.open(QIODevice::ReadOnly);if (!ret){qDebug() << "打開文件失敗";file.close();return 1;}//將文件內(nèi)容讀到doc中ret = doc.setContent(&file);if (!ret){qDebug() << "設(shè)置內(nèi)容失敗";file.close();return 1;}file.close();//獲取doc第一個(gè)節(jié)點(diǎn) 即XML說明QDomNode firstNode = doc.firstChild();//輸出XML說明qDebug() << firstNode.nodeName() << firstNode.nodeValue();return 0;//return a.exec(); }執(zhí)行結(jié)果
“xml” “version=‘1.0’ encoding=‘UTF-8’”
不愿意看到字符串兩邊的引號(hào),可以將源碼中得qDebug()語句更改如下:
//輸出XML說明//qDebug() << firstNode.nodeName() << firstNode.nodeValue();qDebug() << qPrintable(firstNode.nodeName())<< qPrintable(firstNode.nodeValue());執(zhí)行結(jié)果
xml version='1.0' encoding='UTF-8'4.4 繼續(xù)修改main.cpp文件內(nèi)容如下:
#include <QCoreApplication> #include <QDebug> #include <QDomDocument> #include <QDomNode> #include <QtXml> #include <QFile>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);//新建QDomDocument類對象 代表一個(gè)XML文檔QDomDocument doc;//創(chuàng)建test.xml文件QFile file("../test.xml");//以只讀方式打開該文件bool ret = file.open(QIODevice::ReadOnly);if (!ret){qDebug() << "打開文件失敗";file.close();return 1;}//將文件內(nèi)容讀到doc中ret = doc.setContent(&file);if (!ret){qDebug() << "設(shè)置內(nèi)容失敗";file.close();return 1;}file.close();//獲取doc第一個(gè)節(jié)點(diǎn) 即XML說明QDomNode firstNode = doc.firstChild();//輸出XML說明//qDebug() << firstNode.nodeName() << firstNode.nodeValue();qDebug() << qPrintable(firstNode.nodeName())<< qPrintable(firstNode.nodeValue());//返回根元素QDomElement docElem = doc.documentElement();//返回根節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn)QDomNode root = docElem.firstChild();while(!root.isNull()){//如果節(jié)點(diǎn)是元素if (root.isElement()){//將其轉(zhuǎn)換為元素QDomElement e = root.toElement();//返回元素的標(biāo)記 和id屬性的值qDebug() << qPrintable(e.tagName())<< qPrintable(e.attribute("id"));}//下一個(gè)兄弟節(jié)點(diǎn)root = root.nextSibling();}return 0;//return a.exec(); }執(zhí)行結(jié)果如下:
xml version='1.0' encoding='UTF-8' book 01 book 024.5 繼續(xù)修改main.cpp文件,得到所有節(jié)點(diǎn)
#include <QCoreApplication> #include <QDebug> #include <QDomDocument> #include <QDomNode> #include <QtXml> #include <QFile>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);//新建QDomDocument類對象 代表一個(gè)XML文檔QDomDocument doc;//創(chuàng)建test.xml文件QFile file("../test.xml");//以只讀方式打開該文件bool ret = file.open(QIODevice::ReadOnly);if (!ret){qDebug() << "打開文件失敗";file.close();return 1;}//將文件內(nèi)容讀到doc中ret = doc.setContent(&file);if (!ret){qDebug() << "設(shè)置內(nèi)容失敗";file.close();return 1;}file.close();//獲取doc第一個(gè)節(jié)點(diǎn) 即XML說明QDomNode firstNode = doc.firstChild();//輸出XML說明//qDebug() << firstNode.nodeName() << firstNode.nodeValue();qDebug() << qPrintable(firstNode.nodeName())<< qPrintable(firstNode.nodeValue());//返回根元素QDomElement docElem = doc.documentElement();//返回根節(jié)點(diǎn)的第一個(gè)子節(jié)點(diǎn)QDomNode root = docElem.firstChild();while(!root.isNull()){//如果節(jié)點(diǎn)是元素if (root.isElement()){//將其轉(zhuǎn)換為元素QDomElement e = root.toElement();//返回元素的標(biāo)記 和id屬性的值qDebug() << qPrintable(e.tagName())<< qPrintable(e.attribute("id"));//獲取元素e的所有子節(jié)點(diǎn)的列表QDomNodeList list = e.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());}}}//下一個(gè)兄弟節(jié)點(diǎn)root = root.nextSibling();}return 0;//return a.exec(); }使用了childNodes()函數(shù)獲得了元素所有子節(jié)點(diǎn)的列表,然后通過遍歷這個(gè)列表實(shí)現(xiàn)了遍歷其所有子元素。 執(zhí)行結(jié)果
xml version='1.0' encoding='UTF-8' book 01title Qtauthor LiMing book 02title Linuxauthor ZhengGang05. 預(yù)留
06. 附錄
6.1 Qt教程匯總
網(wǎng)址:https://dengjin.blog.csdn.net/article/details/115174639
6.2 源碼下載
網(wǎng)址:【Qt】DOM讀取XML文檔.rar
總結(jié)
以上是生活随笔為你收集整理的【Qt】DOM读取XML文档的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Qt】XML简介
- 下一篇: 【Qt】DOM创建和操作XML文档