一、说明
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();
}
 
七、总结
有点忙,后面两个有时间在解释吧



















