QDomDocument的使用

QDomDocument是QT所封装的类,用来操作XML文件。而xml在项目中的角色常常是用来存储一些配置数据,因此在大部分的项目中会用到两个功能:写XML文件和读取XML文件。具体情况见代码:

#include <QtCore/QCoreApplication>
#include <QDomDocument>
#include <QMap>
#include <QTextStream>
#include <QFile>
#include <iostream>
class CXMLTestData
{
public:
       CXMLTestData();
       CXMLTestData(int num);
       ~CXMLTestData();
       void OutTheData();
       bool          m_bXMLTestData;
       int         m_iTestNum;
       double      m_dChooseNum;
       QString              m_qsXMLDescripe;
       QMap<double , QString>   m_mapXMLData;
       
       bool          m_bFirstChild;
       double      m_dFirstChildChoose;
       QString     m_qsTextNode;
};
CXMLTestData::CXMLTestData()
{
       m_bXMLTestData       = true;
       m_iTestNum = 2226;
       m_dChooseNum = 7920;
       m_qsXMLDescripe = "XML Write Or Read Test!";
       m_mapXMLData[0] = "This is first data.";
       m_mapXMLData[1] = "This is second data.";
       m_mapXMLData[2] = "This is third data";
       m_bFirstChild = true;
       m_dFirstChildChoose = 9898;
       m_qsTextNode = "This is TestNode!";
}
CXMLTestData::CXMLTestData(int num)
{
       m_bXMLTestData = false;
       m_iTestNum = 0;
       m_dChooseNum = 0;
       m_bFirstChild = true;
       m_dFirstChildChoose = 0;
}
CXMLTestData::~CXMLTestData()
{
       
}
void CXMLTestData::OutTheData()
{
       std::cout<< "bXML_TestData = " << m_bXMLTestData << "\n"
              << "iTest_Num = " << m_iTestNum << "\n"
              << "dChoose_Num = " << m_dChooseNum << "\n"
              << "qsXML_Descripe = " << m_qsXMLDescripe.toStdString() << "\n"
              << "mapXMLData_index_0 = " << m_mapXMLData[0].toStdString() << "\n"
              << "mapXMLData_index_1 = " << m_mapXMLData[1].toStdString() << "\n"
              << "mapXMLData_index_2 = " << m_mapXMLData[2].toStdString() << "\n"
              << "bFirstChild = " << m_bFirstChild << "\n"
              << "dFirstChild_Choose = " << m_dFirstChildChoose << "\n"
              << "LastChild = " << m_qsTextNode.toStdString() <<"\n"
              << endl;
}
CXMLTestData myData;
CXMLTestData myReadData(0);
void writeXML()
{
       //保存或者创建一个XML文件,其顺序大部分为:
       //1.对一个QDomDocument对象进行加工,得到需要存储的QDomDocument
       //2.将其保存到一个.xml文件中
       //1.创建加工一个QDomDocument对象
       //(1)创建XML文档得到声明和处理指令,当然也可以添加注释等
       QDomDocument doc;
       //声明和处理指令
       //声明:https://www.cnblogs.com/linyisme/p/5865129.html
       //处理指令:https://www.cnblogs.com/planetwithpig/p/11517923.html
       QDomProcessingInstruction stateInstruct =  doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
       QDomProcessingInstruction dealInstruct =  doc.createProcessingInstruction("xml-stylesheet", "type=\"text/css\"  href=\"style.css\"");
       
       doc.appendChild(stateInstruct);
       doc.appendChild(dealInstruct);
       //也可以补充一些改xml表示的注释
       QDomComment comment = doc.createComment(QString::fromLocal8Bit("这是关于读写XML文件的测试而已"));
       doc.appendChild(comment);
       //(2)创建根节点
       //关于QDomText、QDomElement、QDomComment、QDomProcessingInstruction等都是通过QDomDocument进行创建
       //之后将其appendChild到某个节点中去
       //将根节点创建后,后续的数据填充到根节点中即可
       //===================================================
       //此处数据的填充可以类似到树的添加即可
       //elementRoot.appendChild(LastChild)相当于添加子节点的兄弟节点
       //而如果elementRoot.appendChild(QDomElement::firstChild),再用firstChild.appendChild(ChildChild)相当于根的子节点添加了子节点
       //
       //       QDomElement
       //          /        \
       //  firstChild  LastChild
       //     /
       //  ChildChild
       
       QDomElement elementRoot = doc.createElement("XML-TestData");
       doc.appendChild(elementRoot);
       QDomElement elementFirstChild = doc.createElement("XML-FirstChild");
       elementRoot.appendChild(elementFirstChild);
       QDomElement elementLastChild = doc.createElement("XML-LastChild");
       elementRoot.appendChild(elementLastChild);
       //(3)填充保存数据-元素
       //对于单个节点来说,常用setAttribute,来填充数据
       //数据的存储一般是为<key,value>的对应关系进行存储
       //因此在读取的时候,也会用key进行读取  
       //大概顺序:
       //在某个节点setAttribute填充数据,相当于一个节点内的数据
       //之后用appendChild将这个节点放在某个父节点之下
       //===================================
       //当然你也可以使用doc.createTextNode创建相应的节点去存储数据,之后放在root节点下
       //在创建的时候,推荐对需要存储的元素都设定为<key,value>的形态,这样方便后续的取值
       elementRoot.setAttribute("bXML_TestData", myData.m_bXMLTestData ? 1 : 0);
       elementRoot.setAttribute("iTest_Num",myData.m_iTestNum);
       elementRoot.setAttribute("dChoose_Num",myData.m_dChooseNum);
       elementRoot.setAttribute("qsXML_Descripe", myData.m_qsXMLDescripe);
       for (
              QMap<double, QString>::const_iterator cIter =  myData.m_mapXMLData.constBegin();
              cIter != myData.m_mapXMLData.constEnd(); cIter++
              )
       {
              QDomElement element = doc.createElement("mapXMLData");
              element.setAttribute("mapXMLData_index", *cIter);
              elementRoot.appendChild(element);
       }
       elementFirstChild.setAttribute("bFirstChild", myData.m_bFirstChild ? 1 :  0);
       elementFirstChild.setAttribute("dFirstChild_Choose",  myData.m_dFirstChildChoose);
       QDomText textNode = doc.createTextNode(myData.m_qsTextNode);
       elementLastChild.appendChild(textNode);
       //(4)保存xml文件
       QFile xmlFile("xmlTest.xml");
       
       if (xmlFile.open(QFile::WriteOnly | QFile::Text))
       {
              QTextStream outFile(&xmlFile);
              outFile.setCodec("UTF-8");
              doc.save(outFile, QDomNode::EncodingFromDocument);
              xmlFile.close();
       }
}
void readXML()
{
       // 保存或者创建一个XML文件,其顺序大部分为:
       //1.将文件数据从文件中读取到QDomDocument中
       //2.运用QDomDocument :: elementsByTagName(rootName)获取到根节点
       //3.获取数据,存储到对应地方
       //1.打开文件,并存储到QDomDocument
       QFile xmlFile("xmlTest.xml");
       if (!xmlFile.open(QFile::ReadOnly))
              return;
       QDomDocument doc;
       if (!doc.setContent(&xmlFile))
       {
              xmlFile.close();
              return;
       }
       xmlFile.close();
       //2.找到根节点,将所有名称为"XML-TestData"的节点存入list
       //QDomNodeList QDomDocument::elementsByTagName(const QString& tagname)const
       //返回QDomNodeList,其中包含名称为tagname的文档中的所有元素。节点列表的顺序是在元素树的预遍历中遇到它们的顺序
       //https://doc-snapshots.qt.io/4.8/qdomdocument.html#createProcessingInstruction  QT网页资料库
       //此时获取到的QDomNodeList是“live”的,简单来说就是现在该部QDomDocument节点的值,QDomNodeList里面的值也会变化
       //QDomNode QDomNodeList :: at( int index)const
       //提供此功能是为了确保Qt API的一致性。它相当于项目()。
       //QDomElement QDomNode::toElement()const
       //将QDomNode转换为QDomElement。如果节点不是元素,则返回的对象为null。
       //QDomNode存在许多的类似toElement()的接口,可以转换成为对应的类型
       QDomNodeList nodeList = doc.elementsByTagName("XML-TestData");
       if (nodeList.isEmpty())
              return;
       QDomElement rootElement = nodeList.at(0).toElement();
       //3.获取数据
       if (rootElement.hasAttribute("bXML_TestData"))
              myReadData.m_bXMLTestData =  rootElement.attribute("bXML_TestData").toInt();
       myReadData.m_iTestNum = rootElement.attribute("iTest_Num").toInt();
       myReadData.m_dChooseNum = rootElement.attribute("dChoose_Num").toInt();
       myReadData.m_qsXMLDescripe = rootElement.attribute("qsXML_Descripe");
       myReadData.m_mapXMLData.clear();
       QDomNodeList locp = rootElement.elementsByTagName("mapXMLData");
       for (int i = 0; i < locp.size(); ++i)
       {
              QDomElement element = locp.at(i).toElement();
              myReadData.m_mapXMLData[i] = element.attribute("mapXMLData_index");
       }
       //关于子节点这一点,在文件中的存储方式为:
       //<XML-TestData iTest_Num="2226" dChoose_Num="7920" qsXML_Descripe="XML  Write Or Read Test!" bXML_TestData="1">
       //<XML - FirstChild bFirstChild = "1" dFirstChild_Choose = "9898" / >
       //<XML - LastChild>This is TestNode!< / XML - LastChild>
       //<mapXMLData mapXMLData_index = "This is first data." / >
       //< / XML - TestData>
       //当你想要访问FirstChild节点中的时候,需要获取到FirstChild节点对象进行访问,
       //我测试过使用rootElement
       //获取firstChild.attribute("bFirstChild").toInt();,使用根节点进行访问的时候,其值是获取不到的
       QDomNodeList locpFirst = rootElement.elementsByTagName("XML-FirstChild");
       if(0 < locpFirst.size())
       {
              QDomElement firstElement = locpFirst.at(0).toElement();
              myReadData.m_bFirstChild =  firstElement.attribute("bFirstChild").toInt();
              myReadData.m_dFirstChildChoose =  firstElement.attribute("dFirstChild_Choose").toInt();
       }
       //获取LastChild
       QDomNodeList locpLast = rootElement.elementsByTagName("XML-LastChild");
       if(0 < locpLast.size())
       {
              QDomElement lastElement = locpLast.at(0).toElement();
              myReadData.m_qsTextNode = lastElement.text();
       }
}
int main(int argc, char *argv[])
{
       QCoreApplication a(argc, argv);
       writeXML();
       readXML();
       myReadData.OutTheData();
       return a.exec();
}

运行结果为:

可拓展知识:

在qdom.h代码文件中,列举了许多的节点类型,未进行全面了解可在QT网上教程中查看:

https://doc-snapshots.qt.io/4.8/qtxml.html

  • 11
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
QDomDocumentQt 框架中用于处理 XML 文档的类,以下是一个简单的使用示例: ```cpp #include <QDomDocument> #include <QFile> #include <QDebug> int main() { // 创建一个空的 QDomDocument 对象 QDomDocument doc; // 创建根元素 QDomElement root = doc.createElement("root"); doc.appendChild(root); // 创建子元素 QDomElement child1 = doc.createElement("child1"); child1.setAttribute("name", "Alice"); root.appendChild(child1); QDomElement child2 = doc.createElement("child2"); child2.setAttribute("name", "Bob"); root.appendChild(child2); // 保存到文件 QFile file("example.xml"); if (file.open(QIODevice::WriteOnly)) { QTextStream out(&file); doc.save(out, 4); file.close(); } // 从文件读取并解析 XML if (file.open(QIODevice::ReadOnly)) { if (doc.setContent(&file)) { QDomNodeList children = doc.documentElement().childNodes(); for (int i = 0; i < children.count(); i++) { QDomNode child = children.at(i); if (child.isElement()) { QDomElement element = child.toElement(); QString name = element.tagName(); QString value = element.attribute("name"); qDebug() << "Element: " << name << ", Attribute: " << value; } } } file.close(); } return 0; } ``` 这个示例中,我们首先创建了一个空的 QDomDocument 对象,然后创建了一个根元素和两个子元素,并将它们添加到文档中。接着,我们将文档保存到文件 example.xml 中,然后从文件中读取并解析 XML,输出每个元素的名称和属性值。输出结果如下: ``` Element: child1 , Attribute: Alice Element: child2 , Attribute: Bob ``` 以上就是 QDomDocument 的一个简单使用示例。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值