一、说明
Xml文件的创建、读取、修改、删除以下图格式为例。
二、导入xml
QT += core gui xml
三、创建Xml
void MainWindow::Xml_Write(QString path)
{
//! 打开或创建文件
QFile file(path);
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) return; //! Truncate表示清空原来的内容
//!
QDomDocument doc;
//! 添加头文件
//! <?xml version="1.0" encoding="UTF-8"?>
QDomProcessingInstruction instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild(instruction);
//! 添加根节点 <library> </library>
QDomElement root=doc.createElement("library");
doc.appendChild(root);
//! 子节点一
//! <book time="2021/12/21" id="1"></book>
QDomElement book=doc.createElement("book");
//! 将子节点添加到根节点
root.appendChild(book);
//! 设置子节点属性(2种方式)
book.setAttribute("id",1);
book.setAttribute("time","2021/12/21");
//! 方式一
//! book.setAttribute("id",1);
//! book.setAttribute("time","2021/12/21");
//! 方式二
//! QDomAttr time=doc.createAttribute("time"); //方式二:创建属性 值必须是字符串
//! time.setValue("2222/2/22");
//! book.setAttributeNode(time);
//! 子节点中 子元素一
//! <title>C++ primer</title>
QDomElement title = doc.createElement("title");
book.appendChild(title);
QDomText text = doc.createTextNode("C++ primer");
title.appendChild(text);
//! 子节点中 子元素二
//! <author>Stanley Lippman</author>
title = doc.createElement("author");
book.appendChild(title);
text=doc.createTextNode("Stanley Lippman");
title.appendChild(text);
//! 子节点二
book=doc.createElement("book");
//! 将子节点添加到根节点
root.appendChild(book);
//! 子节点二属性
book.setAttribute("id",2);
book.setAttribute("time","2022/2/22");
//! 子节点二中 子元素一
title=doc.createElement("title");
book.appendChild(title);
text=doc.createTextNode("Thinking in Java");
title.appendChild(text);
//! 子节点二中 子元素一
title=doc.createElement("author");
book.appendChild(title);
text=doc.createTextNode("Bruce Eckel");
title.appendChild(text);
//! 子节点三
book =doc.createElement("phone");
//! 子节点添加到根节点
root.appendChild(book);
//! 子节点三属性
book.setAttribute("id",3);
book.setAttribute("xiaomi","11");
//! 子节点三中 子元素一
title = doc.createElement("price");
book.appendChild(title);
text = doc.createTextNode("999");
title.appendChild(text);
//! 子节点三中 子元素一
title = doc.createElement("discount");
book.appendChild(title);
text = doc.createTextNode("998");
title.appendChild(text);
//输出到文件
QTextStream out_stream(&file);
doc.save(out_stream,4); //缩进4格
}
3.1 “写”说明
//! 1.
> //!
> QDomDocument doc;
//! 2.添加头文件
//!<?xml version="1.0" encoding="UTF-8"?>
> QDomProcessingInstruction instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
> doc.appendChild(instruction);
//! 3.添加根节点(根节点只能有一个,子节点和子节点的子节点个数不限)
//!<library> </library>
> QDomElement root = doc.createElement("library");
> doc.appendChild(root);
//! 4.节点root添加子节点 //! //! //!
QDomElement book=doc.createElement(“book”); //! 将子节点添加到根节点
root.appendChild(book);//! 5.节点book添加节点元素(1)(以子节点Book)
//!<library>
//!....<book id="1" time="2021/12/21"> </book>
//!</library>
> //! 方式一
> book.setAttribute("id",1);
> book.setAttribute("time","2021/12/21");
> //! 方式二:创建元素对象 值必须是字符串
> QDomAttr id=doc.createAttribute("id");
> id.setValue("1");
> book.setAttributeNode(id);
> //! QDomAttr
> time=doc.createAttribute("time");
> time.setValue("2021/12/21");
> book.setAttributeNode(time);
//! 6.子节点book添加子节点
//!<library>
//!....<book id="1" time="2021/12/21">
//!........ <title></title>
//!........ <author></author>
//!....</book>
//!</library>
> QDomElement title = doc.createElement("title");
> book.appendChild(title);
> //!
> QDomElement author = doc.createElement("author");
> book.appendChild(author);
//! 7.添加元素(2)
//!<library>
//!....<book id="1" time="2021/12/21">
//!........<title>C++ primer</title>
//!........ <author>Stanley Lippman</author>
//!....</book>
//!</library>
> //! 子节title点添加元素(2)
> //! 创建文本节点text,存储值
> //! 将文本节点添加到子节点title
> QDomText text = doc.createTextNode("C++ primer");
> title.appendChild(text);
>
> //! 子节anthor点添加元素(2)
> text=doc.createTextNode("Stanley Lippman");
> author.appendChild(text);
> //! 8. 保存 //! 打开或创建文件 QFile file(path);
> if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) return; //!
> Truncate表示清空原来的内容 QTextStream out_stream(&file);
> doc.save(out_stream,4); //缩进4格
四、读
void MainWindow::Xml_Read(QString path)
{
QFile file(path);
if(!file.open(QFile::ReadOnly)) return;
QDomDocument doc;
bool Content = doc.setContent(&file);
file.close();
if(!Content) return;
QDomElement root=doc.documentElement(); //返回根节点
qDebug()<<root.nodeName();
QDomNode node=root.firstChild(); //获得第一个子节点
while(!node.isNull()) //如果节点不空
{
if(node.isElement()) //如果节点是元素
{
QDomElement e=node.toElement(); //转换为元素,注意元素和节点是两个数据结构,其实差不多
//qDebug()<<e.nodeName()<<e.tagName()<<" "<<e.attribute("id")<<" "<<e.attribute("time"); //打印键值对,tagName和nodeName是一个东西
//qDebug()<<e.firstChild().nodeName()<<e.firstChild().toElement().text();
QDomNodeList list=e.childNodes();
for(int i=0;i<list.count();i++) //遍历子元素,count和size都可以用,可用于标签数计数
{
QDomNode n=list.at(i);
if(n.isElement()) qDebug()<<n.nodeName()<<":"<<n.toElement().text();
}
}
node=node.nextSibling(); //下一个兄弟节点,nextSiblingElement()是下一个兄弟元素,都差不多
}
}
4.1 “读”说明
//! 1.打开文件
QFile file(path);
if(!file.open(QFile::ReadOnly)) return;
QDomDocument doc;
bool Content = doc.setContent(&file);
file.close();
if(!Content) return;
//! 2.获取根节点
QDomElement root=doc.documentElement();
//! 打印根节点名
//! qDebug()<<root.nodeName(); // return "library";
//! 3.获取root的第一个子节点
QDomNode node=root.firstChild();
//! 4.获取root的下一个子节点
node=node.nextSibling();
//! 5.获取root的所有节点
QDomNodeList list=root.childNodes();
//! 6.各种属性 //! 是否是空节点,是空节点表示读完
node.isNull();
//! 是否是元素节点,即上述添加了元素的节点
node.isElement();
//! 读元素节点的元素(1) //!
<book id="1" time="2021/12/21">
//! 为方便叙述,此处不具体写获取节点代码,此处node 表示book节点,后续node对应描述的节点,不再做说明
QDomElement e = node.toElement();
qDebug()<<e.nodeName(); // return "book";
qDebug()<<e.tagName(); // return "book";
qDebug()<<e.attribute("id"); // return "1";
qDebug()<<e.attribute("time"); // return "2021/12/21";
//! 读元素节点的元素(1)
//!<book id="1" time="2021/12/21">
//! …<title>C++ primer</title>
//! …<author>Stanley Lippman</author>
//!</book>
//! node 表示book节点
QDomElement e = node.toElement();
QDomNodeList list=e.childNodes();
QDomNode n=list.at(0);
if(n.isElement()) qDebug()<<n.nodeName()<<":"<<n.toElement().text(); // return "title : C++ primer";
n=list.at(1);
if(n.isElement()) qDebug()<<n.nodeName()<<":"<<n.toElement().text(); // return "author : Stanley Lippman";
五、添加子节点
void MainWindow::Xml_Add(QString path)
{
//打开文件
QFile file(path); //相对路径、绝对路径、资源路径都可以
if(!file.open(QFile::ReadOnly))
return;
//增加一个一级子节点以及元素
QDomDocument doc;
bool Content = doc.setContent(&file);
file.close();
if(!Content) return;
QDomElement root=doc.documentElement();
QDomNode node=root.firstChild(); //获得第一个子节点
int number = 0;
while(!node.isNull()) //如果节点不空
{
number++;
node= node.nextSibling();
}
qDebug()<<number;
QDomElement book=doc.createElement("book");
book.setAttribute("id",number+1);
book.setAttribute("time","1813/1/27");
QDomElement title=doc.createElement("title");
QDomText text=doc.createTextNode("Pride and Prejudice");
title.appendChild(text);
book.appendChild(title);
QDomElement author=doc.createElement("author");
text=doc.createTextNode("Jane Austen");
author.appendChild(text);
book.appendChild(author);
root.appendChild(book);
if(!file.open(QFile::WriteOnly|QFile::Truncate)) return;//先读进来,再重写,如果不用truncate就是在后面追加内容,就无效了
//输出到文件
QTextStream out_stream(&file);
doc.save(out_stream,4); //缩进4格
file.close();
}
六、删除节点
void MainWindow::Xml_Delete(QString path)
{
QFile file(path); //相对路径、绝对路径、资源路径都可以
if(!file.open(QFile::ReadOnly)) return;
//删除一个一级子节点及其元素,外层节点删除内层节点于此相同
QDomDocument doc;
bool Content = doc.setContent(&file);
file.close();
if(!Content) return;
//! 根节点元素
QDomElement root=doc.documentElement();
//! 根据子节点标签名获取所有子节点
QDomNodeList list=doc.elementsByTagName("book"); //由标签名定位
for(int i=0;i<list.count();i++)
{
QDomElement e=list.at(i).toElement();
if(e.attribute("time")=="2007/5/25") root.removeChild(list.at(i)); //以属性名定位,类似于hash的方式,warning:这里仅仅删除一个节点,其实可以加个break
}
if(!file.open(QFile::WriteOnly|QFile::Truncate)) return;
//输出到文件
QTextStream out_stream(&file);
doc.save(out_stream,4); //缩进4格
file.close();
}
七、总结
有点忙,后面两个有时间在解释吧