Qt-xml文件-DOM
使用DOM读写XML文档
(Document Object Model,文档对象模型),是W3C的推荐标准,它提供了一个接口来访问和改变一个XML文件的内容、结构,可以将XML文档表示为一个存储在内存中具有层次的树视图。文档本身由QDomDocument对象来表示,而文档树中的所有的DOM节点都是QDomNode类的子类。
1 所使用类继承关系
QDomNode
|----- QDomDocument ----- 文档本身
|----- QDomElement ----- 元素
|----- QDomProcessingInstruction -----XML说明
|----- QDomAttr ----- 属性
|----- QDomCharacterData
|----- QDomText ----- 文本内容
|----- QDomComment -----注释 <!-- this is a comment -->

QDomNode可以表示所有的DOM节点,比如这里的说明、元素、属性和文本等,然后使用对应的isProcessingInstruction()、isElement()、isAttr()和isText()等函数来判断是否是该类型的元素;如果是,可以使用toProcessingInstruction()、toElement()、toAttr()和toText()等函数转换为具体的节点类型。
2 使用DOM写入XML
//生成xml文件
QDomDocument doc;
//添加处理指令即xml说明
QDomProcessingInstruction instruction; //说明的格式要正确,多或少写空格都会导致读取xml文件失败
instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild(instruction);
//添加根元素
QDomElement root = doc.createElement("书库");
doc.appendChild(root);
//添加图书元素及其子元素
QDomElement book = doc.createElement("图书");
QDomAttr id = doc.createAttribute("编号");
id.setValue(QString("1"));
book.setAttributeNode(id);
QDomElement title = doc.createElement("书名");
QDomElement author = doc.createElement("作者");
QDomText text;
text = doc.createTextNode("Qt");
title.appendChild(text);
text = doc.createTextNode("shiming");
author.appendChild(text);
book.appendChild(title);
book.appendChild(author);
root.appendChild(book);
//添加第二个图书元素及其子元素
book = doc.createElement("图书");
id = doc.createAttribute("编号");
id.setValue(QString("2"));
book.setAttributeNode(id);
title = doc.createElement("书名");
author = doc.createElement("作者");
text = doc.createTextNode("Linxu");
title.appendChild(text);
text = doc.createTextNode("yafei");
author.appendChild(text);
book.appendChild(title);
book.appendChild(author);
root.appendChild(book);
QFile file("../myDOM2/my.xml");
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return;
QTextStream out(&file);
//将文档保存到文件,4为子元素缩进字符数
doc.save(out,4);
file.close();

3 使用DOM读取XML文档
QDomDocument doc;
QFile file("../myDom1/my.xml");
if(!file.open(QIODevice::ReadOnly))
{
return;
}
//将文件内容读取到doc中
if(!doc.setContent(&file))
{
file.close();
return;
}
file.close();
//获得doc的第一个结点,即xml说明
QDomNode firstNode = doc.firstChild();
qDebug() << qPrintable(firstNode.nodeName()) << qPrintable(firstNode.nodeValue());
//qDebug() << firstNode.nodeName() << " " << firstNode.nodeValue();
//返回根元素
QDomElement docElem = doc.documentElement();
//返回根元素的第一个子结点
QDomNode n = docElem.firstChild();
while(!n.isNull())
{
if(n.isElement())
{
//将其转换为元素
QDomElement e = n.toElement();
//返回元素标记和属性的值
qDebug() << qPrintable(e.tagName()) << qPrintable(e.attribute("id"));
//获取e元素的所有子结点列表
QDomNodeList list = e.childNodes();
for(int i = 0; i < list.count(); i++)
{
QDomNode node = list.at(i);
if(node.isElement())
{
qDebug() << " " << qPrintable(node.toElement().tagName())
<< qPrintable(node.toElement().text());
}
}
}
//转到下一个兄弟结点
n = n.nextSibling();
}
4 添加一个节点
ui->listWidget->clear();
ui->listWidget->addItem(tr("无法添加!"));
QFile file("../myDOM2/my.xml");
if(!file.open(QIODevice::ReadOnly))
return;
QDomDocument doc;
if(!doc.setContent(&file))
{
file.close();
return;
}
file.close();
QDomElement root = doc.documentElement();
QDomElement book = doc.createElement("图书");
QDomAttr id = doc.createAttribute("编号");
QDomElement title = doc.createElement("书名");
QDomElement author = doc.createElement("作者");
QDomText text;
QString num = root.lastChild().toElement().attribute("编号");
int count = num.toInt() + 1;
id.setValue(QString::number(count));
book.setAttributeNode(id);
text = doc.createTextNode(ui->lineEdit_bookName->text());
title.appendChild(text);
text = doc.createTextNode(ui->lineEdit_author->text());
author.appendChild(text);
book.appendChild(title);
book.appendChild(author);
root.appendChild(book);
//QFile file("../myDOM2/my.xml");
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return;
QTextStream out(&file);
//将文档保存到文件,4为子元素缩进字符数
doc.save(out,4);
file.close();
ui->listWidget->clear(); //最后更改显示为添加成功
ui->listWidget->addItem(tr("添加成功"));
5 查找、更新、删除
ui->listWidget->clear();
ui->listWidget->addItem(tr("没有找到相关内容"));
QFile file("../myDOM2/my.xml");
if(!file.open(QIODevice::ReadOnly))
return;
QDomDocument doc;
if(!doc.setContent(&file))
{
file.close();
return;
}
file.close();
QDomNodeList list = doc.elementsByTagName("图书");
for(int i = 0; i < list.count(); i++)
{
QDomElement e = list.at(i).toElement();
if(e.attribute("编号") == ui->lineEdit_id->text())
{
if(operate == "delete")
{
QDomElement root = doc.documentElement();
root.removeChild(list.at(i));
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return ;
QTextStream out(&file);
doc.save(out,4);
file.close();
ui->listWidget->clear();
ui->listWidget->addItem(tr("删除成功!"));
}
else if(operate == "update")
{
QDomNodeList childList = list.at(i).childNodes();
childList.at(0).toElement().firstChild().setNodeValue(ui->lineEdit_bookName->text());
childList.at(1).toElement().firstChild().setNodeValue(ui->lineEdit_author->text());
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return ;
QTextStream out(&file);
doc.save(out,4);
file.close();
ui->listWidget->clear();
ui->listWidget->addItem(tr("更新成功!"));
}
else if(operate == "find")
{
ui->listWidget->clear();
ui->listWidget->addItem(e.tagName() + e.attribute("编号"));
QDomNodeList childList = e.childNodes();
for(int i = 0; i < list.count(); i++)
{
QDomNode node = childList.at(i);
if(node.isElement())
{
ui->listWidget->addItem(" " + node.toElement().tagName() + ":"
+ node.toElement().text());
}
}
}
}
}

6 使用中遇到的问题
问题1:setcontent() 读取mxl文件失败
<?xml version="1.0" encoding="UTF-8"?> xml说明格式不正确,中间少了或多了空格
问题2:QDomElement 如果没有孩子或者内容就显示单标签,否则就是标签对
问题3:当xml文件以gb2312方式编码时,含有中文标签或属性时,使用setContext方式读取
文件时会失败。解决方式:使用读取文本文件的方式读入xml内容,再构造QDomDocument。
保存xml文件时需要指定保存编码格式,使用流的方式。
//读xml
QFile file("F:/example/vs2010/txt/gbk.xml");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
return;
}
QTextStream in(&file);
in.setCodec("gb2312");
QString s = in.readAll();
QDomDocument doc = QDomDocument(s);
QDomDocument doc;
//添加处理指令即xml说明
QDomProcessingInstruction instruction; //说明的格式要正确,多或少写空格都会导致读取xml文件失败
instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"gb2312\"");
doc.appendChild(instruction);
//写xml
QFile file("F:/example/vs2010/txt/gbk.xml");
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
return;
QTextStream out(&file);
//将文档保存到文件,4为子元素缩进字符数
out.setCodec("gb2312");
//doc.save(out,4);
QString str = doc.toString(4);
out << str;
//doc.save(out,4,QDomNode::EncodingFromTextStream);
file.close();
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)