Qt Xml的读、写、修改、删除

一、说明

Xml文件的创建、读取、修改、删除以下图格式为例。
Qt Xml的读、写、修改、删除_第1张图片

二、导入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;

    //! 添加头文件
    //! 
    QDomProcessingInstruction instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
    doc.appendChild(instruction);

    //! 添加根节点  
    QDomElement root=doc.createElement("library");
    doc.appendChild(root);
    //! 子节点一
    //! 
    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);

    //! 子节点中 子元素一
    //! C++ primer
    QDomElement title = doc.createElement("title");
    book.appendChild(title);
    QDomText text = doc.createTextNode("C++ primer");
    title.appendChild(text);

    //! 子节点中 子元素二
    //! Stanley Lippman
    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.添加头文件
//!

> QDomProcessingInstruction instruction =  doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\""); 
> doc.appendChild(instruction);

//! 3.添加根节点(根节点只能有一个,子节点和子节点的子节点个数不限)
//!

> QDomElement root = doc.createElement("library");
> doc.appendChild(root);

//! 4.节点root添加子节点 //! //! //!
QDomElement book=doc.createElement(“book”); //! 将子节点添加到根节点
root.appendChild(book);

//! 5.节点book添加节点元素(1)(以子节点Book)
//!
//! ....
//!

> //! 方式一
> 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添加子节点
//!
//! ....
//! ........
//! ........
//! ....
//!

>   QDomElement title = doc.createElement("title"); 
>   book.appendChild(title); 
>   //!   
>   QDomElement author = doc.createElement("author");
>   book.appendChild(author);

//! 7.添加元素(2)
//!
//! ....
//! ........C++ primer
//! ........ Stanley Lippman
//! ....
//!

> //! 子节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()<
            //qDebug()<
            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()<

//! 3.获取root的第一个子节点

QDomNode node=root.firstChild(); 

//! 4.获取root的下一个子节点

node=node.nextSibling();

//! 5.获取root的所有节点

QDomNodeList list=root.childNodes();

//! 6.各种属性 //! 是否是空节点,是空节点表示读完

node.isNull();

//! 是否是元素节点,即上述添加了元素的节点

node.isElement();

//! 读元素节点的元素(1) //!
//! 为方便叙述,此处不具体写获取节点代码,此处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)
//!
//! …C++ primer
//! …Stanley Lippman
//!
//! 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();
}

七、总结

有点忙,后面两个有时间在解释吧

你可能感兴趣的:(qt,qt,xml,c++)