天天看点

Qt的Xml操作QDomDocumentQt的Xml操作QDomDocument

Qt的Xml操作QDomDocument

Qt对于Xml的支持是很好的,一些我们需要的操作应有尽有,下面简单介绍一下怎样使用。主要有以下几点使用:

  1. 写xml到文件
  2. 读xml
  3. 添加节点到xml
  4. 删除xml中某节点信息
  5. 修改xml中某节点信息

准备工作

  1. .pro加入QT += xml
  2. 需要include QDomDocument QTextStream QFile三个头文件

WriteXml

直接上代码

void writeXml()
{
    QDomDocument doc;
    QDomProcessingInstruction xmlInstruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"");
    QDomComment comment = doc.createComment(QString::fromLocal8Bit("离开是为了更好的归来"));
    QDomProcessingInstruction styleInstruction = doc.createProcessingInstruction("xml-stylesheet", "type=\"text/css\" href=\"style.css\"");
    doc.appendChild(xmlInstruction);  // 开始文档(XML 声明)
    doc.appendChild(comment);  // 注释
    doc.appendChild(styleInstruction);  // 处理指令
    // 根元素 <Blogs>
    QDomElement root = doc.createElement("Books");
    root.setAttribute("Version", "1.0");  // 属性
    doc.appendChild(root);

    // 元素 <Blog>
    QDomElement child = doc.createElement("Book");
    root.appendChild(child);

    // 元素 <作者>、<时间>、<个人说明>
    QDomElement author = doc.createElement(QString::fromLocal8Bit("作者"));
    QDomElement home = doc.createElement(QString::fromLocal8Bit("时间"));
    QDomElement instruction = doc.createElement(QString::fromLocal8Bit("个人说明"));
    child.appendChild(author);
    child.appendChild(home);
    child.appendChild(instruction);

    // 元素的文本数据
    QDomText authorText = doc.createTextNode(QString::fromLocal8Bit("Vincent"));
    QDomText homeText = doc.createTextNode("2017年4月13日");
    QDomText instructionText = doc.createTextNode(QString::fromLocal8Bit("大宋枢密院常任委员会_委员"));
    author.appendChild(authorText);
    home.appendChild(homeText);
    instruction.appendChild(instructionText);

    // 保存 XML 文件
    QString strFile("Books.xml");
    QFile file(strFile);
    // 只写模式打开文件
    if (file.open(QFile::WriteOnly | QFile::Text))
    {
        QTextStream out(&file);
        doc.save(out, QDomNode::EncodingFromDocument);
        file.close();
    }
}
void writeXML()
{
    //打开或创建文件
    QString fileName{"test.xml"};
    QFile file(fileName);
    //QIODevice::Truncate表示清空原来的内容
    if(!file.open(QFile::WriteOnly|QFile::Truncate))
        return;

    //创建xml文档在内存中
    QDomDocument doc;
    //添加处理命令
    QDomProcessingInstruction instruction;
    instruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
    //创建注释
    QDomComment comment;
    comment = doc.createComment(QString::fromLocal8Bit("离开是为了更好的归来"));
    QDomProcessingInstruction styleInstruction;
    styleInstruction= doc.createProcessingInstruction("xml-stylesheet", "type=\"text/css\" href=\"style.css\"");
    doc.appendChild(instruction); //文档开始声明
    doc.appendChild(comment);
    doc.appendChild(styleInstruction);  // 处理指令


    //添加根节点
    QDomElement root=doc.createElement("library");
    root.setAttribute("Version","2.1");
    doc.appendChild(root);
    //添加第一个子节点及其子元素
    QDomElement book=doc.createElement("book");
    //方式一:创建属性  其中键值对的值可以是各种类型
    book.setAttribute("id",);
    //方式二:创建属性 值必须是字符串
    QDomAttr time=doc.createAttribute("time");
    time.setValue("2013/6/13");
    book.setAttributeNode(time);
    QDomElement title=doc.createElement("title"); //创建子元素
    QDomText text; //设置括号标签中间的值
    text=doc.createTextNode("C++ primer");
    book.appendChild(title);
    title.appendChild(text);
    QDomElement author=doc.createElement("author"); //创建子元素
    text=doc.createTextNode("Stanley Lippman");
    author.appendChild(text);
    book.appendChild(author);
    //添加节点book做为根节点的子节点
    root.appendChild(book);

    //添加第二个子节点及其子元素
    book=doc.createElement("book");
    book.setAttribute("id",);
    time=doc.createAttribute("time");
    time.setValue("2007/5/25");
    book.setAttributeNode(time);
    title=doc.createElement("title");
    text=doc.createTextNode("Thinking in Java");
    book.appendChild(title);
    title.appendChild(text);

    author=doc.createElement("author");
    text=doc.createTextNode("Bruce Eckel");
    author.appendChild(text);
    book.appendChild(author);
    root.appendChild(book);

    //输出到文件
    QTextStream out_stream(&file);
    doc.save(out_stream,); //缩进4格
    file.close();
}
           

ReadXml

上代码

void readXML()
{
    //打开或创建文件
        QFile file("test.xml");
        if(!file.open(QFile::ReadOnly))
            return;

        QDomDocument doc;
        //设置wangfei1.xml到文档
        if(!doc.setContent(&file))
        {
            file.close();
            return;
        }

        file.close();

        //返回根节点
        QDomElement root=doc.documentElement();
        qDebug()<<root.nodeName();
        //如果xml根元素有属性(Version)将输出,Vinsion是用户自定义的属性,没有继续执行下一条命令
        if (root.hasAttribute("Version"))  // 属性
            qDebug() << root.attribute("Version");
        /**********根元素之上(XML 声明、注释等)**********/
        QDomNode node = root.previousSibling();
        while (!node.isNull())
        {
            switch (node.nodeType())
            {
            case QDomNode::ProcessingInstructionNode :
            {
                QDomProcessingInstruction instruction = node.toProcessingInstruction();
                //输出处理指令,是用户自定义的,比如字符串“name”对应处理指令得到名字,这个命令是用户写的
                qDebug() << instruction.target() << instruction.data();
                if (QString::compare(instruction.target(), "xml") == ) // 开始文档(XML 声明)
                {
                    //cout<<"处理命令xml"<<endl;
                    // ...
                }
                else if (QString::compare(instruction.target(), "xml-stylesheet") == ) // 处理指令
                {
                    //cout<<"处理命令xml-stylesheet"<<endl;
                    // ...
                }
                break;
            }
            case QDomNode::CommentNode :
            {
                QDomComment comment = node.toComment();
                qDebug() << comment.data();
                break;
            }
            default:
                break;
            }
            node = node.previousSibling();
        }

        //获得第一个子节点
        node=root.firstChild();
        while(!node.isNull())  //如果节点不空
        {
            if(node.isElement()) //如果节点是元素
            {
                //转换为元素
                QDomElement element=node.toElement();
                if (!element.isNull())// 节点的确是一个元素
                {
                    //输出第一个节点,包括第一个节点的属性,这个属性需要指定属性值,才能输出,如果没有输出空
                    qDebug()<<element.tagName()<<" "<<element.attribute("id")<<" "<<element.attribute("time");
                    QDomNodeList list=element.childNodes();
                    for(int i=;i<list.count();++i)
                    {
                        QDomNode n=list.at(i);
                        //node = list.at(i);
                        if(node.isElement())
                        {
                            qDebug()<<n.nodeName()<<":"<<n.toElement().text();
                            element = n.toElement();
                            //qDebug()<<element.nodeName()<<":"<<element.toElement().text();
                            if (QString::compare(element.tagName(), QStringLiteral("作者")) == )
                            {
                                // ...处理命令
                                //cout<< "处理命令作者"<<endl;
                            }
                            else if (QString::compare(element.tagName(), QStringLiteral("时间")) == )
                            {
                                //cout<<"处理命令时间"<<endl;
                                // ...处理命令
                            }
                            else if (QString::compare(element.tagName(), QStringLiteral("个人说明")) == )
                            {
                                //cout<<"处理命令个人说明"<<endl;
                                // ...处理命令
                            }
                        }

                    }
                }
            }
            //下一个兄弟节点
            node=node.nextSibling();
        }
}
           

AddXml

void addXML()
{
    //打开文件
    QFile file("test.xml");
    if(!file.open(QFile::ReadOnly))
        return;
    //增加一个一级子节点以及元素
    QDomDocument doc;
    if(!doc.setContent(&file))
    {
        file.close();
        return;
    }
    file.close();
    //创建根节点
    QDomElement root = doc.documentElement();
    //创建next子节点book
    QDomElement book = doc.createElement("book");
    book.setAttribute("id",);
    book.setAttribute("time","1813/1/27");
    QDomElement title = doc.createElement("title");
    QDomText text;
    text = doc.createTextNode("Pride and Prejudice");
    //添加text内容到title节点
    title.appendChild(text);
    //添加title到book节点
    book.appendChild(title);
    //添加book到根节点
    root.appendChild(book);

    if(!file.open(QFile::WriteOnly|QFile::Truncate))
        return;
    //输出到文件
    QTextStream out_stream(&file);
    doc.save(out_stream,); //以缩进4格方式输出,也有其他输出方式(格式)
    file.close();
}
           

DeleteXml

void deleteXML()
{
    //打开文件
    QFile file("test.xml");
    if(!file.open(QFile::ReadOnly))
        return;

    //删除一个一级子节点及其元素,外层节点删除内层节点于此相同
    QDomDocument doc;
    if(!doc.setContent(&file))
    {
        file.close();
        return;
    }
    file.close();

    QDomElement root=doc.documentElement();
    //由标签名定位,本标签为book,以后可以是用string类型的字符串替换,实现动态
    QDomNodeList list=doc.elementsByTagName("book");

    //删除方式一,通过标签book后面的属性删除<book>到</book>
    for(int i=;i<list.count();i++)
    {
        //转化为元素
        QDomElement e=list.at(i).toElement();
        //找到time是2007/5/25这一条数据将其删除
        if(e.attribute("time")=="2007/5/25")
            root.removeChild(list.at(i));
    }
    //删除方式二,可以通过索引直接删除
//    root.removeChild(list.at(1));

    if(!file.open(QFile::WriteOnly|QFile::Truncate))
        return;
    //输出到文件
    QTextStream out_stream(&file);
    doc.save(out_stream,); //缩进4格
    file.close();
}
           

AmendXml

void amendXML()
{
    //打开文件
    QFile file("wangfei1.xml");
    if(!file.open(QFile::ReadOnly))
        return;

    //更新一个标签项,如果知道xml的结构,直接定位到那个标签上定点更新
    //或者用遍历的方法去匹配tagname或者attribut,value来更新
    QDomDocument doc;
    //设置wangfei.xml读到doc文档
    if(!doc.setContent(&file))
    {
        file.close();
        return;
    }
    file.close();

    /**
     *    知道xml结构,直接定位修改
      *   提取根节点
      *
      */
    QDomElement root=doc.documentElement();
    //以book标签存入list
//    QDomNodeList list=root.elementsByTagName("book");
//    QDomNode listNode=list.at(list.size()-2).firstChild();
//    QDomNode oldnode=listNode.firstChild();
//    //把title改成Emma
//    listNode.firstChild().setNodeValue("aaaaaaa");
//    QDomNode newnode=listNode.firstChild();
//    listNode.replaceChild(newnode,oldnode);


    //使用遍历方法选择要修改的元素
//    QDomNodeList lists =doc.childNodes();
//    QDomNodeList list=root.elementsByTagName("book");

    QDomNode node = root.firstChild();

    //QDomNodeList list=root.elementsByTagName("book");

    while(!node.isNull())  //如果节点不空
    {
        if(node.isElement()) //如果节点是元素
        {
            //转换为元素
            QDomElement element=node.toElement();
            if (!element.isNull() && element.attribute("id") == "3")// 节点的确是一个元素
            {
                //输出第一个节点,包括第一个节点的属性,这个属性需要指定属性值,才能输出,如果没有输出空
                //qDebug()<<element.tagName()<<" "<<element.attribute("id")<<" "<<element.attribute("time");
                QDomNodeList list=element.childNodes();
                for(int i=;i<list.count();++i)
                {
                    QDomNode n=list.at(i);
                    //node = list.at(i);
                    if(node.isElement())
                    {
                        //qDebug()<<n.nodeName()<<":"<<n.toElement().text();
                        element = n.toElement();
                        //与上面qDebug效果相同
                        //qDebug()<<element.nodeName()<<":"<<element.toElement().text();


                        //这个if可以不需要,如果需要精确定位,以防数据相同所以要加这个嵌套if
                        if (QString::compare(element.tagName(), QStringLiteral("title")) == )
                        {

                            if("Pride and Prejudice" == element.toElement().text())
                            {
                                // ...处理命令,在这个if里可以遍历想要的节点进行修改
                                //新建一个旧的node缓存
                                QDomNode oldNode = n.firstChild();
                                n.firstChild().setNodeValue("changchun1");
                                //新建一个新的newNode子节点
                                QDomNode newNode = n.firstChild();
                                //使用replaceChild替换node
                                n.replaceChild(newNode,oldNode);
                            }

                        }

                        else if (QString::compare(element.tagName(), QStringLiteral("时间")) == )
                        {
                            //cout<<"处理命令时间"<<endl;
                            // ...处理命令
                        }
                        else if (QString::compare(element.tagName(), QStringLiteral("个人说明")) == )
                        {
                            //cout<<"处理命令个人说明"<<endl;
                            // ...处理命令
                        }
                    }

                }
            }
        }
        //下一个兄弟节点
        node=node.nextSibling();
    }


    if(!file.open(QFile::WriteOnly|QFile::Truncate))
        return;
    //输出到文件
    QTextStream out_stream(&file);
    doc.save(out_stream,); //缩进4格
    file.close();

}