Qt4可以实现json操作,也可以实现xml文件操作。
xml文件主要有两种操作方式,1是dom操作,2是stream操作。
首先来看一下dom操作。
示例的文件如下:
<?xml version='1.0' encoding='UTF-8'?>
<文件库>
<论文 编号="1">
<标题>孙悟空</标题>
<作者>看我72变</作者>
</论文>
<论文 编号="2">
<标题>沙师弟</标题>
<作者>不行吧</作者>
</论文>
<论文 编号="3">
<标题>三藏</标题>
<作者>阿弥陀佛</作者>
</论文>
</文件库>
可以分为信息行,根节点和子节点。节点又分为tag和value,这和json是大致一样的。
首先是实现读取文件:
// 读xml文件
void Widget::on_pushButton_clicked()
{
QString filename = getOpenFile();
if(filename==QString(".xml")) return;
readXml2List(filename);
}
// 获取文件名
QString Widget::getOpenFile()
{
// 打开文件
QString filedir = QCoreApplication::applicationDirPath();
QString filename = QFileDialog::getOpenFileName(this,"打开xml文件",filedir,"xml (*.xml)");
return filename;
}
// 读xml文件到domdoc对象
QDomDocument Widget::readXml(QString filename)
{
QDomDocument doc; // 创建Dom文档对象
QFile file(filename); // 创建文件对象
if(!file.open(QIODevice::ReadOnly)) return doc; // 打开文件对象 只读 如果出错就返回
doc.setContent(&file);
file.close();
return doc;
}
// 读xml并显示
void Widget::readXml2List(QString filename)
{
// 读xml文件到doc对象
QDomDocument doc = readXml(filename);
if(doc.toString()=="")
return;
ui->plainTextEdit->appendPlainText("已打开文件: "+filename+"\n");
ui->plainTextEdit->appendPlainText(doc.toString());
// 定义Dom节点对象 将第1个节点赋给他
QDomNode firstNode = doc.firstChild();
// 输出到text
ui->plainTextEdit->appendPlainText(firstNode.nodeName()+": "+firstNode.nodeValue());
// 返回根元素
QDomElement docElem = doc.documentElement();
// 返回根元素的第1个子节点
QDomNode n = docElem.firstChild();
// 如果节点不为空 则转到下1个节点
while(!n.isNull())
{
// 如果节点是元素
if(n.isElement())
{
// 将其转换为元素
QDomElement e = n.toElement();
// 返回元素标记和id属性值
ui->plainTextEdit->appendPlainText(e.tagName()+": "+e.attribute("编号"));
ui->listWidget->addItem(e.tagName()+": "+e.attribute("编号"));
// 获得元素e的所有子节点列表
QDomNodeList list = e.childNodes();
// 遍历该列表
for(int i = 0; i<list.count(); i++)
{
QDomNode node = list.at(i);
if(node.isElement())
{
ui->plainTextEdit->appendPlainText(" "+node.toElement().tagName()+": "+node.toElement().text());
ui->listWidget->addItem(" "+node.toElement().tagName()+": "+node.toElement().text());
}
}
}
// 转到下一个兄弟节点
n = n.nextSibling();
}
}
实现效果如下:
为了清晰展示读取效果,用list和plain两种方式来显示。
之后是写文件,先实现写示例:
// 写示例xml文件
void Widget::writeTestXml(QString filename)
{
QDomDocument doc;
// 添加xml说明
QDomProcessingInstruction ins;
ins = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild(ins);
// 添加根元素
QDomElement root = doc.createElement(QString("文件库"));
doc.appendChild(root);
// 添加第1个文献元素及其子元素
QDomElement paper = doc.createElement(QString("论文"));
QDomAttr id = doc.createAttribute(QString("编号"));
QDomElement title = doc.createElement(QString("标题"));
QDomElement author = doc.createElement(QString("作者"));
QDomText text;
id.setValue(QString("1"));
paper.setAttributeNode(id);
text = doc.createTextNode(QString("三国演义"));
title.appendChild(text);
text = doc.createTextNode(QString("罗贯中"));
author.appendChild(text);
paper.appendChild(title);
paper.appendChild(author);
root.appendChild(paper);
// 添加第2个文献元素及其子元素
paper = doc.createElement(QString("论文"));
id = doc.createAttribute(QString("编号"));
title = doc.createElement(QString("标题"));
author = doc.createElement(QString("作者"));
id.setValue(QString("2"));
paper.setAttributeNode(id);
text = doc.createTextNode(QString("茶馆"));
title.appendChild(text);
text = doc.createTextNode(QString("老舍"));
author.appendChild(text);
paper.appendChild(title);
paper.appendChild(author);
root.appendChild(paper);
// 写doc到xml文件
writeXml(filename, doc);
}
写文件之后,马上调用读文件来显示:
最后,在实现一下节点的增删改查:
代码如下:
void Widget::doXml(QString filename, const QString operate)
{
// 读xml文件到doc
QDomDocument doc = readXml(filename);
if(doc.toString()=="") return;
// 以标签名进行查找
QDomNodeList list = doc.elementsByTagName(QString("论文"));
for(int i = 0; i<list.count(); i++)
{
QDomElement e = list.at(i).toElement();
// 如果属性值相同
if(e.attribute(QString("编号"))==ui->lineEdit_3->text())
{
if(operate=="delete")
{
QDomElement root = doc.documentElement();
root.removeChild(list.at(i));// 从根节点删除
writeXml(filename,doc);
ui->listWidget->clear();
readXml2List(filename);
}
else if(operate=="update")
{
QDomNodeList child = list.at(i).childNodes();
child.at(0).toElement().firstChild().setNodeValue(ui->lineEdit->text());
child.at(1).toElement().firstChild().setNodeValue(ui->lineEdit_2->text());
writeXml(filename,doc);
ui->listWidget->clear();
readXml2List(filename);
}
else if(operate=="find")
{
ui->listWidget->addItem(e.tagName()+e.attribute(QString("编号")));
QDomNodeList childlist = e.childNodes();
for(int i = 0; i<childlist.count(); i++)
{
QDomNode node = childlist.at(i);
ui->listWidget->clear();
ui->listWidget->addItem(" "+node.toElement().tagName()+": "+node.toElement().text());
}
}
}
}
}
总结:dom操作可以便捷的实现增删改查。用这种方式可以满足文件model的信息表建立。
疑问:如何使用model形式在listview或者treeview上显示呢,怎么弄mvc
如何实现在treewidget上的显示?