本人采用的是QDom方式读写XML,然后用QTreeWidget显示。
最终达到的目的是:
首先,通过代码创建一个XML文件,例如:
然后更改其中的Text节点的内容,就像这样:
最后再用程序读出来:
话不多说,先上代码,最后再解释:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTreeWidget>
#include <QFrame>
//自定义对象--输入
typedef struct FileInput
{
QString Name;
int Text;
int Count;
}FileInput;
//自定义对象--接收
typedef struct FileReceive
{
QString Name;
int Text;
int Count;
}FileReceive;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QTreeWidget* m_pTreeWidget;
QFrame* m_pTreeFrame;
FileInput inputFile;
void openFile(QString path);//读取XML
void changeXML(QString path);//更改XML
private slots:
void slot_readXMl();
void slot_saveXMl();//写XML
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include <QPushButton>
#include <QHBoxLayout>
#include <QFile>
#include <QFileDialog>
#include <QDomDocument>
#include <QTextStream>
#include <QDebug>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setMinimumSize(400,400);
setMaximumSize(400,400);
m_pTreeWidget = new QTreeWidget(this);
m_pTreeWidget->setGeometry(0,0,400,300);
QFrame* pButtonFrame = new QFrame(this);
pButtonFrame->setGeometry(0,300,400,100);
QPushButton* pReadBtn = new QPushButton(pButtonFrame);
pReadBtn->setText("保存XML");
connect(pReadBtn,SIGNAL(clicked()),this,SLOT(slot_saveXMl()));
QPushButton* pQuitBtn = new QPushButton(pButtonFrame);
pQuitBtn->setText("读取XML");
connect(pQuitBtn,SIGNAL(clicked()),this,SLOT(slot_readXMl()));
QHBoxLayout* pHLayout = new QHBoxLayout(pButtonFrame);
pHLayout->addWidget(pReadBtn);
pHLayout->addWidget(pQuitBtn);
inputFile.Name = "Name";
inputFile.Text = 10086;
inputFile.Count = 2;
}
MainWindow::~MainWindow()
{
}
//读取XML
void MainWindow::openFile(QString path)
{
changeXML(path); //更改XML
FileReceive receiveFile;
QString name;
QDomDocument doc;
QFile file(path);
if (!file.open(QIODevice::ReadOnly))
{
return;
}
if (!doc.setContent(&file))
{
file.close();
return;
}
QDomElement rootElem = doc.documentElement();
QDomNode rootNode = rootElem.firstChild();
QTreeWidgetItem *root = new QTreeWidgetItem(m_pTreeWidget, QStringList(rootElem.tagName()));
while(!rootNode.isNull())
{
QDomElement fileElem = rootNode.toElement();
if(!fileElem.isNull())
{
name = fileElem.tagName();
if(name == "Name")
{
for(QDomNode childNode = fileElem.firstChild(); !childNode.isNull();
childNode = childNode.nextSibling())
{
QDomText childText = childNode.toText();
receiveFile.Name = childText.data();
QTreeWidgetItem *itemFileName = new QTreeWidgetItem(root,
QStringList(name+tr(" ")+receiveFile.Name));
root->addChild(itemFileName);
}
}
else if(name == "Text")
{
for(QDomNode childNode = fileElem.firstChild(); !childNode.isNull();
childNode = childNode.nextSibling())
{
QDomText childText = childNode.toText();
receiveFile.Text = childText.data().toInt();
QTreeWidgetItem *itemText = new QTreeWidgetItem(root,
QStringList(name+tr(" ")
+QString("%1").arg(receiveFile.Text)));
root->addChild(itemText);
}
}
else if(name == "Count")
{
for(QDomNode childNode = fileElem.firstChild(); !childNode.isNull();
childNode = childNode.nextSibling())
{
QDomText childText = childNode.toText();
receiveFile.Count = childText.data().toInt();
QTreeWidgetItem *itemCount = new QTreeWidgetItem(root,
QStringList(name+tr(" ")
+QString("%1").arg(receiveFile.Count)));
root->addChild(itemCount);
}
}
}
rootNode = rootNode.nextSibling();
}
file.close();
}
//更改XML
void MainWindow::changeXML(QString path)
{
QString name;
QDomDocument doc;
QFile file(path);
if (!file.open(QIODevice::ReadOnly))
{
return;
}
if (!doc.setContent(&file))
{
file.close();
return;
}
file.close();
QDomElement rootElem = doc.documentElement();
QDomNode rootNode = rootElem.firstChild();
while(!rootNode.isNull())
{
QDomElement fileElem = rootNode.toElement();
if(!fileElem.isNull())
{
name = fileElem.tagName();
if(name == "Text")
{
QDomElement newnode = doc.createElement("Text");
QDomText text = doc.createTextNode("10000");
newnode.appendChild(text);
rootElem.replaceChild(newnode,rootNode);
}
}
rootNode = rootNode.nextSibling();
}
QString xml = doc.toString();
if(!file.open(QFile::WriteOnly|QFile::Truncate))
{
return;
}
QTextStream out(&file);
out<<xml;
file.close();
}
//写XML
void MainWindow::slot_saveXMl()
{
QString dirPath = QFileDialog::getSaveFileName (this,tr("save file"),
" ",tr("XML files (*.xml)"));
QDomDocument doc;
QString strHeader("version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild( doc.createProcessingInstruction("xml", strHeader));
QFile file(dirPath);
if (!file.open(QIODevice::WriteOnly))
{
return;
}
QDomElement rootFile = doc.createElement("File");
doc.appendChild(rootFile);
QDomElement rootFileName = doc.createElement("Name");
rootFile.appendChild(rootFileName);
QDomText textFileName = doc.createTextNode(inputFile.Name);
rootFileName.appendChild(textFileName);
QDomElement rootText = doc.createElement("Text");
rootFile.appendChild(rootText);
QDomText textText = doc.createTextNode(QString("%1").arg(inputFile.Text));
rootText.appendChild(textText);
QDomElement rootCount = doc.createElement("Count");
rootFile.appendChild(rootCount);
QDomText textCount = doc.createTextNode(QString("%1").arg(inputFile.Count));
rootCount.appendChild(textCount);
QString xml = doc.toString();
QTextStream txtOutput(&file);
txtOutput<<xml;
file.close();
}
void MainWindow::slot_readXMl()
{
QString filePath = QFileDialog::getOpenFileName(this,tr("open file")," ",
tr("XML files (*.xml);;ALL files (*.*)"));
openFile(filePath);
}
代码解释如下:
这里我用两个结构体储存XML文件的值,写的时候从结构体读值,读的时候,将值写入结构体中,方便调用,当然,你也可以直接读取,相信看一下Qt帮助文档就可以轻松操作,在这里,我主要解释一下修改XML中结点的代码。
我这里使用的changeXML(QString path)函数,更改的。
//更改XML
void MainWindow::changeXML(QString path)
{
QString name;
QDomDocument doc;
QFile file(path);
if (!file.open(QIODevice::ReadOnly))
{
return;
}
if (!doc.setContent(&file))
{
file.close();
return;
}
file.close();
QDomElement rootElem = doc.documentElement();
QDomNode rootNode = rootElem.firstChild();
while(!rootNode.isNull())
{
QDomElement fileElem = rootNode.toElement();
if(!fileElem.isNull())
{
name = fileElem.tagName();
if(name == "Text")
{
QDomElement newnode = doc.createElement("Text");
QDomText text = doc.createTextNode("10000");
newnode.appendChild(text);
rootElem.replaceChild(newnode,rootNode);
}
}
rootNode = rootNode.nextSibling();
}
QString xml = doc.toString();
if(!file.open(QFile::WriteOnly|QFile::Truncate))
{
return;
}
QTextStream out(&file);
out<<xml;
file.close();
}
首先和读取XML文件一样,先遍历,当遍历到想要更改的节点时(我这里是Text节点),中心思想是,再写一个更改后的Text结点,然后用replaceChild(const QDomNode &newChild, const QDomNode &oldChild)函数更改。
如图:
仔细观察,可以发现,这和写XML文件时操作基本一样:
上图是写XML文件,只不过把中间的添加结点去掉了,最后用replaceChild()实现替换。
记住,更改完最后一定要重新载入XML,要不然无法更改,即
QString xml = doc.toString();
if(!file.open(QFile::WriteOnly|QFile::Truncate))
{
return;
}
QTextStream out(&file);
out<<xml;
file.close();
不可省略!!!!!
最后,附上一张图,提示一下其他注意事项
rootNode为旧的节点,即待更改的节点。
最终实现结果:
首先将更改XML语句注释掉。
点击保存XML
保存
打开看一下,写XML成功
再点击读取XML
读取成功
将更改XML注释去掉
再点击读取XML
更改成功,读取成功
打开XML文件看一下
源码下载:http://download.csdn.net/download/fan_xingwang/10246768