- By刘立博
- 2020-12-19 23:23:31
- 964人已阅读
DOM方式读写XML的优劣
由于需要将 XML 文档转换为树形结构存储到内存中,所以内存占用较大.但操作方便,适合频繁读写的场景
QDomDocument
QT所有对XML的操作方法均封装在QDomDocument之中,要使用QDomDocument需要添加XML模块
添加XML模块
编辑QT项目配置文件xmlBom.pro,在已添加的模块后追加XML模块
QT += core gui xml
QDomDocument常用方法及示例
createProcessingInstruction
创建一个可以插入到XML文档的Dom头声明
示例
声明dom头<?xml version="1.0" encoding="UTF-8"?>
doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
createElement
创建一个可以插入DOM树的元素节点
示例
如创建一个名为users的元素节点
QDomElement body = doc.createElement("users");
createTextNode
创建一个文本节点(设置节点的正文)
示例
设置元素节点name的正文为"my name"
QDomElement user_name = doc.createElement("name");
user_name.appendChild(doc.createTextNode("my name"));
setAttribute
设置节点属性
示例
设置name节点gender属性为male
QDomElement user_name = doc.createElement("name");
user_name.setAttribute("gender","male");
appendChild
将节点追加至某个节点
示例
将body节点追加至doc节点(设置子节点)
doc.appendChild(body);
setContent
将byte数组解析为XML DOM树
示例
将一个XML文件解析为DOM树
doc.setContent(xmlFile);
documentElement
获取XML文档的根节点
示例
获取DOM doc中的根节点
QDomElement root = doc.documentElement();
childNodes
获取某节点下的子节点列表
示例
获取root节点下的子节点列表
QDomNodeList userList = doc.documentElement().childNodes();
toElement
将节点对象转为元素对象
示例
将user节点下的第一个子节点转为元素对象
QDomNodeList eleList = user.childNodes();
QDomElement name = eleList.at(0).toElement();
Text
获取转为元素对象节点的正文
示例
获取元素name的正文
QDomElement name = eleList.at(0).toElement();
Qstring nameText = name.text();
Attribute
获取转为元素对象节点的属性
示例
获取元素name中gender属性的值
QDomElement name = eleList.at(0).toElement();
String genderValue = name.attribute("gender");
一个栗子:读取\写入一个用户列表XML文件
XML文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE users>
<users>
<user>
<name gender="male">张三</name>
<age>18</age>
</user>
<user>
<name gender="female">李四</name>
<age>19</age>
</user>
<user>
<name gender="male">王五</name>
<age>20</age>
</user>
</users>
写入XML文件
用户选择文件保存路径后,构建DOM树,写入XML文件
void MainWindow::on_pushButton_2_clicked()
{
QString path = QFileDialog::getSaveFileName(this,"请选择一个XML文件",QDir::currentPath(),"XML(*.xml)");
if(path.isEmpty()) QMessageBox::critical(this,"打开文件失败","请选择一个XML文件");
xmlFile->setFileName(path);
xmlFile->open(QIODevice::WriteOnly);
QDomDocument doc("users");
QDomProcessingInstruction header = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild(header);
QDomElement body = doc.createElement("users");
// user
QStringList arrayNames;
arrayNames << "张三" << "李四" << "王五";
QStringList arrayGenders;
arrayGenders << "male" << "female" << "male";
QStringList arrayAges ;
arrayAges << "18" << "19" << "20";
for(int i=0;i<arrayNames.size();i++)
{
QDomElement user = doc.createElement("user");
QDomElement user_name = doc.createElement("name");
user_name.setAttribute("gender",arrayGenders.at(i));
user_name.appendChild(doc.createTextNode(arrayNames.at(i)));
QDomElement user_age = doc.createElement("age");
user_age.appendChild(doc.createTextNode(arrayAges.at(i)));
user.appendChild(user_name);
user.appendChild(user_age);
body.appendChild(user);
}
doc.appendChild(body);
//save file
QTextStream stream(xmlFile);
stream.setCodec("UTF-8");
doc.save(stream,4);
QMessageBox::information(this,"保存成功",xmlFile->fileName());
xmlFile->close();
}
测试效果
读取XML文件
用户选择文件读取路径后,将XML转为DOM树,迭代并显示XML文件内容
void MainWindow::on_pushButton_1_clicked()
{
QString path = QFileDialog::getOpenFileName(this,"请选择一个XML文件",QDir::currentPath(),"XML(*.xml)");
if(path.isEmpty()) QMessageBox::critical(this,"打开文件失败","请选择一个XML文件");
xmlFile->setFileName(path);
xmlFile->open(QIODevice::ReadOnly);
QDomDocument doc("users");
doc.setContent(xmlFile);
xmlFile->close();
QDomNodeList userList = doc.documentElement().childNodes();
for(int i = 0;i<userList.size();i++)
{
QDomNode user = userList.at(i);
QDomNodeList eleList = user.childNodes();
QDomElement name = eleList.at(0).toElement();
QDomElement age = eleList.at(1).toElement();
ui->plainTextEdit->appendPlainText(
" name: "+name.text()+
" gander:"+name.attribute("gender")+
" age:"+age.text()+"\r\n"
);
}
}
测试效果