对XML文件操作有三种:
1) QXmlStreamReader:一种快速的基于流的方式访问良格式 XML 文档,只需读取文档一次,然后像一个遍历器从头到尾一次性处理 XML 文档,期间不会有反复的情况。
2) DOM(Document Object Model):将整个 XML 文档读入内存,构建成一个树结构,允许程序在树结构上向前向后移动导航。
3) SAX(Simple API for XML):提供大量虚函数,以事件的形式处理 XML 文档。
本文记录使用DOM方式对XML文件操作的相关学习笔记。
在XML文件中,其实每一个节点都是一个Element,对文件操作使用QDomDocument类,元素使用QDomElement类,QDomProcessingInstruction类是头部格式,QDomAttr类表示节点的属性。
创建一个XML文件:
QFile file(filePath);//关联文件名字
if(true == file.exists())
{
cout<<"文件以及存在";
return;
}else
{
//只写方式打开文件
bool isOk = file.open(QIODevice::WriteOnly);
if (true == isOk)
{
//创建XML文档
QDomDocument doc;
//创建XML头部格式
QDomProcessingInstruction ins;
ins = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
//追加元素
doc.appendChild(ins);
//根节点元素
QDomElement root = doc.createElement("root");
doc.appendChild(root);
//保存
QTextStream stream(&file);//文本流关联文件
doc.save(stream,4);//4表示缩进字符
file.close();
}else
{
cout<<"writeOnly error";
return;
}
}
创建的结果是xml头部定义,和一个空的根节点root,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<root/>
向上面创建的XML文件中加入更多Element:
QFile file(filePath);
bool isOk = file.open(QIODevice::ReadOnly);
if(isOk)//打开成功
{
//file和xml文档对象关联
QDomDocument doc;
isOk = doc.setContent(&file);
if(isOk)//如果关联成功
{
file.close();//关闭文档
//获取根节点元素
QDomElement root = doc.documentElement();
//获取当前时间
QDateTime date = QDateTime::currentDateTime();
QString dateStr = date.toString("yyyy-MM-dd");//2020-04-25 月份MM要大写,mm表示分钟
//判断根节点下有没有子节点
if(root.hasChildNodes())//如果有子节点
{
//查找最后一个子节点
QDomElement lastEmt = root.lastChildElement();
if(lastEmt.attribute("date")==dateStr)
{//如果有当天的日期
//继续写一个Child
//当前时间获取
QDateTime time = QDateTime::currentDateTime();
QString timeStr = time.toString("hh-mm-ss");
//创建时间元素
QDomElement timeEmt = doc.createElement("时间");
//创建时间属性
QDomAttr timeAttr = doc.createAttribute("time");
//设置属性值
timeAttr.setNodeValue(timeStr);
//节点和属性关联
timeEmt.setAttributeNode(timeAttr);
//把时间节点加入到日期节点后
lastEmt.appendChild(timeEmt);
}else//如果没有当天日期
{
//创建日期子节点元素
QDomElement dateEmt = doc.createElement("日期");
//创建date属性
QDomAttr dateAttr = doc.createAttribute("date");
//设置属性的值
dateAttr.setNodeValue(dateStr);
//节点和属性关联
dateEmt.setAttributeNode(dateAttr);
//把日期节点追加到根节点
root.appendChild(dateEmt);
//继续写一个Child
//当前时间获取
QDateTime time = QDateTime::currentDateTime();
QString timeStr = time.toString("hh-mm-ss");
//创建时间元素
QDomElement timeEmt = doc.createElement("时间");
//创建时间属性
QDomAttr timeAttr = doc.createAttribute("time");
//设置属性值
timeAttr.setNodeValue(timeStr);
//节点和属性关联
timeEmt.setAttributeNode(timeAttr);
//把时间节点加入到日期节点后
dateEmt.appendChild(timeEmt);
}
}else//如果没有子节点
{
//创建日期子节点元素
QDomElement dateEmt = doc.createElement("日期");
//创建date属性
QDomAttr dateAttr = doc.createAttribute("date");
//设置属性的值
dateAttr.setNodeValue(dateStr);
//节点和属性关联
dateEmt.setAttributeNode(dateAttr);
//把日期节点追加到根节点
root.appendChild(dateEmt);
//继续写一个Child
//当前时间获取
QDateTime time = QDateTime::currentDateTime();
QString timeStr = time.toString("hh-mm-ss");
//创建时间元素
QDomElement timeEmt = doc.createElement("时间");
//创建时间属性
QDomAttr timeAttr = doc.createAttribute("time");
//设置属性值
timeAttr.setNodeValue(timeStr);
//节点和属性关联
timeEmt.setAttributeNode(timeAttr);
//把时间节点加入到日期节点后
dateEmt.appendChild(timeEmt);
}
//保存文件
isOk = file.open(QIODevice::WriteOnly);
if(isOk)
{
QTextStream stream(&file);
doc.save(stream,4);
file.close();
}
}else
{
cout<<"setContent error";
return;
}
}else
{
cout<<"readOnly error";
return;
}
得到的结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<日期 date="2020-04-25">
<时间 time="14-34-59"/>
</日期>
</root>
1、创建根节点
QDomDocument doc;
QDomElement root = doc.createElement("root");
doc.appendChild(root);
2、写入XML文件(文件只读方式打开,成功后进行下列操作)
QTextStream stream(&file);//文本流关联文件
doc.save(stream,4);//4表示缩进字符
3、file和xml文档对象关联使用setContent函数
QDomDocument doc;
doc.setContent(&file);
4、获取xml文档中的根节点
QDomElement root = doc.documentElement();
5、查找最后一个节点元素
QDomElement lastEmt = root.lastChildElement();
6、创建子节点
//创建日期子节点元素
QDomElement dateEmt = doc.createElement("日期");
//创建date属性
QDomAttr dateAttr = doc.createAttribute("date");
//设置属性的值
dateAttr.setNodeValue(dateStr);
//节点和属性关联
dateEmt.setAttributeNode(dateAttr);
//把日期节点追加到根节点
root.appendChild(dateEmt);