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();
});
}
演示截图(可以点击修改):
示例代码地址:csdnDemo: CSDN博客示例代码存档