Qt使用QDom解析XML文件

        QDom处理XML文件时,一次性读入整个XML文档,在内存中构造一棵树。我们可以访问这棵树,在树上移动,比如移动到下一个节点,或者返回到上一个节点,也可以修改这棵树,以及将这棵树保存为XML文件。

        在DOM树中有很多函数,这些函数很多都是返回QDomNode类型,我们可以通过函数isXXX(),如isAttr()等来判断节点类型,也可以通过toXXX()来转换节点类型。

帮助文档的示例:

QDomDocument d;
d.setContent(someXML);
QDomNode n = d.firstChild();
while (!n.isNull()) {
    if (n.isElement()) {
        QDomElement e = n.toElement();
        cout << "Element name: " << e.tagName() << Qt::endl;
        break;
    }
    n = n.nextSibling();
}

         下面示例演示解析一个XML文件,并可以修改XML文件项的参数值并写回XML文件。

主要代码:

void XmlFileRW::getXmlFile(QString path){

    mapNode.clear();
    if(tree != nullptr){
        disconnect(tree);
        tree->setParent(nullptr);
        delete tree;
    }

    tree = new QTreeWidget(this);
    tree->setStyleSheet("QTreeWidget::item{height:25px}");
    ui->mainLayout->addWidget(tree);
    QFile file(path);
    if(!file.open(QIODevice::ReadOnly)) return;
    if(!doc.setContent(&file)){
        file.close();
        return;
    }
    file.close();

    tree->clear();
    tree->setColumnCount(5);
    tree->setColumnWidth(0,350);
    tree->setColumnWidth(1,350);
    itemStart = new QTreeWidgetItem;
    itemStart->setText(0, "start to processing");
    tree->addTopLevelItem(itemStart);

    QDomElement docElem = doc.documentElement();
    QDomNode n = docElem.firstChild();
    while(!n.isNull()) {
        QDomElement e = n.toElement();
        if(!e.isNull()) {
//            qDebug() << e.tagName();
            QTreeWidgetItem *item = new QTreeWidgetItem(itemStart);
            item->setText(0,e.tagName());
            for(int i= 0; i < e.attributes().size(); i++){
//                qDebug() << e.attributes().item(i).nodeName();
//                qDebug() << e.attributes().item(i).nodeValue();
                item->setText(i+1,e.attributes().item(i).nodeName() + ":" + e.attributes().item(i).nodeValue());
            }
//            if(e.isText()) qDebug()<<"hh"<setText(0,e.tagName());
            for(int i= 0; i < e.attributes().size(); i++){
//                qDebug() << e.attributes().item(i).nodeName();
//                qDebug() << e.attributes().item(i).nodeValue();
                item->setText(i+1,"attributes:"+e.attributes().item(i).nodeName() + ":" + e.attributes().item(i).nodeValue());
            }
            QDomNode ee = e.firstChild();
            while (!ee.isNull()) {
                if(ee.isText())
                {
//                    qDebug() << ee.toText().nodeValue();
                    item->setText(e.attributes().size()+1,ee.toText().nodeValue());
                }
                ee = ee.nextSibling();
            }
//            connect(item,&QTreeWidgetItem::)
            mapNode[item] = e;
            traverXmlFile(e, item);
        }
        n = n.nextSibling();
    }
}

void XmlFileRW::slotfixMsg(QTreeWidgetItem *item, QString tagName, QString attributes, QString text){
    QLayoutItem *child;
     while ((child = ui->gridLayout->takeAt(0)) != 0)
     {
         if(child->widget())
         {
             child->widget()->setParent(NULL);
         }
         delete child->widget();
     }
     ui->gridLayout->setAlignment(Qt::AlignCenter);

     QLabel *tagLabel = new QLabel("TagName:");
     QLineEdit *tagEdit = new QLineEdit(tagName);
     ui->gridLayout->addWidget(tagLabel,0,0);
     ui->gridLayout->addWidget(tagEdit,0,1);

     QList attrLabelList;
     QList attrEditList;
     QStringList attr = attributes.split("||");
     attr.removeOne("");
     for(int i =0 ; i < attr.size();i++){
         if(attr.at(i).split(":").size() !=3) continue;
         QLabel *label = new QLabel(attr.at(i).split(":").at(1));
         QLineEdit *edit = new QLineEdit(attr.at(i).split(":").at(2));
         ui->gridLayout->addWidget(label,i+1,0);
         ui->gridLayout->addWidget(edit,i+1,1);
         attrLabelList.append(label);
         attrEditList.append(edit);
     }

     QLineEdit *txtEdit{nullptr};
     if(text != ""){
         QLabel *tagLabel = new QLabel("Text:");
         QLineEdit *tagEdit = new QLineEdit(text);
         ui->gridLayout->addWidget(tagLabel,attr.size()+1,0);
         ui->gridLayout->addWidget(tagEdit,attr.size()+1,1);
         txtEdit = tagEdit;
     }

     QPushButton *btn = new QPushButton("SaveChange");
     ui->gridLayout->addWidget(btn,attr.size()+2,0,1,2);
     connect(btn, &QPushButton::clicked, [=]{
         item->setText(0,tagEdit->text());
         mapNode[item].toElement().setTagName(tagEdit->text());

         for(int i = 0;i < attrLabelList.size(); i++){
             QString tmpAttrName = attrLabelList.at(i)->text();
             QString tmpAttrValue = attrEditList.at(i)->text();
             item->setText(i+1,"attributes:"+tmpAttrName+":"+tmpAttrValue);
             mapNode[item].toElement().removeAttribute(tmpAttrName);
             mapNode[item].toElement().setAttribute(tmpAttrName, tmpAttrValue);
         }

         if(txtEdit != nullptr && !mapNode[item].toElement().firstChild().isNull()){
             mapNode[item].toElement().firstChild().toText().setNodeValue(txtEdit->text());
             item->setText(attrLabelList.size()+1,txtEdit->text());
         }

         QFile file(xmlPath);
         if (!file.open(QFile::WriteOnly|QFile::Truncate | QFile::Text))//1.QFile::WriteOnly如果文件不存在,则创建;2.QFile::Truncate打开的同时清空
         {
             return false;
         }
         QTextStream stream(&file );
         stream.setCodec("utf-8");
         doc.save(stream,4,QDomNode::EncodingFromTextStream);
         file.close();
     });
}

演示截图(可以点击修改):

Qt使用QDom解析XML文件_第1张图片

 示例代码地址:csdnDemo: CSDN博客示例代码存档

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