QDomDocument操作xml文件

一、背景

项目中需要用到xml工单的生成,每次都要进行脑残的粘贴复制修改xml任务工单,作为程序员的我们,怎么甘心做这么重复无聊的工作呢?于是就写了一个小工具来操作xml,实现自动化,主要使用QDomDocument操作。废话不说了,直接上码!

二、代码如下

/mainwindow.h*/

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtXml/QDomDocument>
#include <QtXml/QDomElement>
#include <QFileInfoList>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:

    // 输入xml文件
    void on_pushButton_clicked();

    // 输入需要的文件夹路径
    void on_pushButton_2_clicked();

    // 确定插入
    void on_pushButton_3_clicked();

private:
    // 根据文件路径搜索文件下面的文件
    QFileInfoList getFileList(QString path);
    // 在input结点插入需要的file结点
    bool insertInputItem(QDomDocument doc,QString outputPath,QFileInfoList fileInfoList, QDomElement inputElem);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

/**********************************mainwindow.cpp***********************************/
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QTextStream>
#include <QtXml/QDomNode>
#include <QDebug>
#pragma execution_character_set("utf-8")

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

//************************************
// 函数名称: on_pushButton_clicked
// 函数说明: 【private槽函数】输入xml文件
// 返 回 值: void
// 作    者:ISmileLi
// 作成日期:
// 修改记录:
//************************************
void MainWindow::on_pushButton_clicked()
{
    QString filePath = QFileDialog::getOpenFileName(this,tr("xml file"),"/home",tr("file(*.xml)"));
    ui->lineEdit->setText(filePath);
    ui->lineEdit->setEnabled(false);
}

//************************************
// 函数名称: on_pushButton_2_clicked
// 函数说明: 【private槽函数】输入需要的文件夹路径
// 返 回 值: void
// 作    者:ISmileLi
// 作成日期:
// 修改记录:
//************************************
void MainWindow::on_pushButton_2_clicked()
{
    QString filePath = QFileDialog::getExistingDirectory(this,tr("open directory"),"/home",
                                                         QFileDialog::ShowDirsOnly
                                                         | QFileDialog::DontResolveSymlinks);
    ui->lineEdit_2->setText(filePath);
    ui->lineEdit_2->setEnabled(false);
}

//************************************
// 函数名称: on_pushButton_3_clicked
// 函数说明: 【private槽函数】确定插入
// 返 回 值: void
// 作    者:ISmileLi
// 作成日期:
// 修改记录:
//************************************
void MainWindow::on_pushButton_3_clicked()
{
    QString inputXmlFile = ui->lineEdit->text();
    QString inputFilesPath = ui->lineEdit_2->text();
    QString replaceText = ui->lineEdit_3->text();
    QString outputPath = ui->lineEdit_4->text();

    if(inputXmlFile.isEmpty() || inputFilesPath.isEmpty() || replaceText.isEmpty() || outputPath.isEmpty())
    {
        QMessageBox::information(NULL,"title","please check your input is complete!!!");
    }

    QFileInfoList fileInfoList = getFileList(inputFilesPath);
    if(fileInfoList.isEmpty())
    {
        QMessageBox::information(NULL,"title","can't find file!");
        return ;
    }

    QDomDocument doc;
    QFile file(inputXmlFile);
    if(!file.open(QIODevice::ReadWrite))
    {
        return;
    }
    if(!doc.setContent(&file))
    {
        file.close();
        return;
    }


    QDomElement docElem = doc.documentElement();
    if(!docElem.hasChildNodes())
    {
        return;
    }
    QDomNodeList rootChildList = docElem.childNodes();
    if(rootChildList.isEmpty())
        return;
    for(int i=0; i<rootChildList.length(); i++)
    {
        QDomNode nodeItem = rootChildList.at(i);
        QString nodeName = nodeItem.nodeName();
        if(nodeName == "inputlist")
        {
            QDomNodeList inputListChilds = nodeItem.childNodes();
            if(inputListChilds.isEmpty())
            {
                break;
            }
            bool bFind = false;
            for(int j=0; j<inputListChilds.length(); j++)
            {
                QDomNode inputNode = inputListChilds.at(j);
                QString inputName = inputNode.nodeName();
                QDomElement inputElem = inputNode.toElement();
                QString attrName = inputElem.attribute("description");
                if(inputName == "input" && attrName == replaceText)
                {
                    bFind = true;
                    insertInputItem(doc,outputPath,fileInfoList,inputElem);
                }
            }
            if(!bFind)
            {
                QString indexStr = QString("%1").arg(inputListChilds.length());
                QDomElement inputElem = doc.createElement("input");
                inputElem.setAttribute("description",replaceText);
                inputElem.setAttribute("index",indexStr);
                QDomElement inputListElem = nodeItem.toElement();
                inputListElem.appendChild(inputElem);
                insertInputItem(doc,outputPath,fileInfoList,inputElem);
            }
        }
    }
    file.resize(0);
    QTextStream out(&file);
    doc.save(out,4);
    file.flush();
    file.close();
    QMessageBox::information(NULL,"title","insert over!",NULL);
}

//************************************
// 函数名称: getFileList
// 函数说明: 【private】根据文件路径搜索文件下面的文件
// 返 回 值: bool
// 参    数: QString path
// 作    者:ISmileLi
// 作成日期:
// 修改记录:
//************************************
QFileInfoList MainWindow::getFileList(QString path)
{
    QDir dir(path);
    QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
    QFileInfoList folderList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);

    for(int i=0; i<folderList.size(); i++)
    {
        QString name = folderList.at(i).absoluteFilePath();
        qDebug() << name << endl;
        QFileInfoList chileFileList = getFileList(name);
        fileList.append(chileFileList);
    }
    return fileList;
}

//************************************
// 函数名称: insertInputItem
// 函数说明: 【private】在input结点插入需要的file结点
// 返 回 值: bool
// 参    数: QDomDocument doc
// 参    数: QString outputPath
// 参    数: QFileInfoList fileInfoList
// 参    数: QDomElement inputElem
// 作    者:ISmileLi
// 作成日期:
// 修改记录:
//************************************
bool MainWindow::insertInputItem(QDomDocument doc,QString outputPath,QFileInfoList fileInfoList, QDomElement inputElem)
{
    for(int k=0; k<fileInfoList.length(); k++)
    {
        QFileInfo fileInfo = fileInfoList.at(k);
        QString fileName = fileInfo.fileName();
        QString tempFilePath = outputPath + "/" + fileName;
        QDomElement inputChildElem = doc.createElement("file");
        inputChildElem.setAttribute("time","2000-00-00");
        inputElem.appendChild(inputChildElem);
        QDomText inputChildText = doc.createTextNode(tempFilePath);
        inputChildElem.appendChild(inputChildText);
    }
    if(!inputElem.hasChildNodes())
        return false;
    return true;
}

三、运行效果

在这里插入图片描述

xml文件变化:
在这里插入图片描述

在这里插入图片描述

四、遇到的小问题

1、使用QDomDocument需要在.pro文件中加上xml。
2、引入头文件要#include <QtXml/QDomDocument>引入才对
3、可能会出现链接错误,此时把之前生成的exe文件夹删除再重新编译即可。

posted @ 2019-03-11 20:39  ISmileLi  阅读(57)  评论(0编辑  收藏  举报