来源https://www.devbean.net/2013/07/qt-study-road-2-read-xml-with-stream/
建立XML文档
<bookindex>
<entry term="sidebearings">
<page>10</page>
<page>34-35</page>
<page>307-308</page>
</entry>
<entry term="subtraction">
<entry term="of pictures">
<page>115</page>
<page>244</page>
</entry>
<entry term="of vectors">
<page>9</page>
</entry>
</entry>
</bookindex>
在Pro文件中声明XML
QT += core gui xml
头文件
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
//读取file
bool readFile(const QString &fileName);
private:
//读取截点
//父节点
//子节点(QTreeWidgetItem *parent)
//读取bookindex节点
void readBookindexElement();
//读取entry节点
void readEntryElement(QTreeWidgetItem *parent);
//读取page节点
void readPageElement(QTreeWidgetItem *parent);
//无关节点跳过
void skipUnknownElement();
QTreeWidget *treeWidget;
QXmlStreamReader reader;
方法依次为:
1.读取文件
2.读取父节点bookindex
3.读取子节点entry(接受传过来的父节点 bookindex)
4.读取子节点page(接受传过来的父节点 entry)
5.跳过无关节点
读取文件:
bool MainWindow::readFile(const QString &fileName)
{
QFile file(fileName);
if(!file.open(QFile::ReadOnly | QFile::Text)){
QMessageBox::information(this,tr("open error"),tr("connot read file %1").arg(fileName));
qDebug()<<"error";
return false;
}
qDebug()<<QDir::currentPath();
//将file设置为QXmlStreamReader的设备(Stream从file中读取内容)
//Sets the current device to device.
//Setting the device resets the stream to its initial state.
reader.setDevice(&file);
//判断文件是否读到末尾
while(!reader.atEnd()){
//判断是否是开始元素
if(reader.isStartElement()){
//判断读取的根标签是否是bookindex
if(reader.name() == "bookindex"){
//是bookindex 往下读取
readBookindexElement();
}else {
reader.raiseError(tr("Not a valid book file"));
}
}else {
reader.readNext();
}
}
//文件记得关闭
file.close();
if(reader.hasError()){
QMessageBox::information(this,tr("Error"),tr("Filed to parse file %1").arg(fileName));
return false;
}else if(file.error() != QFile::NoError){
QMessageBox::information(this,tr("Error"),tr("Cannot read file %1").arg(fileName));
return false;
}
return true;
}
读取bookindex节点:
void MainWindow::readBookindexElement()
{
//Q_ASSERT()加断言 若进函数的时候 StartElement状态,或者说标签不是 bookindex,就认为出错
Q_ASSERT(reader.isStartElement() && reader.name()=="bookindex");
//往下读取
reader.readNext();
while (!reader.atEnd()) {
//判断是结束节点,跳出
if(reader.isEndElement()){
reader.readNext();
break;
}
if(reader.isStartElement()){
//(bookindex的子元素为entry)开始处理entry
if(reader.name() == "entry"){
//读取entry节点,(隐藏根节点)
readEntryElement(treeWidget->invisibleRootItem());
}else {
//没读到entry节点 跳过
skipUnknownElement();
}
}else {
reader.readNext();
}
}
}
读取entry节点
//接受一个QTreeWidgetItem指针作为根节点.这个节点被当做这个 entry 标签在QTreeWidget中的根节点。
void MainWindow::readEntryElement(QTreeWidgetItem *parent)
{
QTreeWidgetItem *item = new QTreeWidgetItem(parent);
//item index=0 属性为"term"的值
//QXmlStreamReader::attributes() Returns the attributes of a StartElement.
item->setText(0,reader.attributes().value("term").toString());
reader.readNext();
while (!reader.atEnd()) {
if(reader.isEndElement()){
reader.readNext();
break;
}
if(reader.isStartElement()){
//读到entry节点
if(reader.name() == "entry"){
readEntryElement(item);
//page节点
}else if(reader.name() == "page"){
readPageElement(item);
}else{
//无节点 跳过
skipUnknownElement();
}
}else {
reader.readNext();
}
}
}
读取page
void MainWindow::readPageElement(QTreeWidgetItem *parent)
{
//获取文本
QString page = reader.readElementText();
if(reader.isEndElement()){
reader.readNext();
}
//QTreeWidgetItem::text(int column)返回指定列的text
QString allPages = parent->text(1);
if(!allPages.isEmpty()){
//用","分割
allPages += ",";
}
allPages += page;
parent->setText(1,allPages);
}
无关节点跳过
void MainWindow::skipUnknownElement()
{
reader.readNext();
//没有结束
while (!reader.atEnd()) {
//结束
if(reader.isEndElement()){
reader.readNext();
break;
}
//继续跳过读取。
if(reader.isStartElement()){
skipUnknownElement();
}else {
reader.readNext();
}
}
}
在MainWindow函数中 声明
setWindowTitle(tr("xml reader"));
treeWidget = new QTreeWidget(this);
QStringList headers;
//设置头 Items Pages
headers<<"Items"<<"Pages";
treeWidget->setHeaderLabels(headers);
setCentralWidget(treeWidget);
//读取不到 用绝对路径读取成功 添加到资源路径读取成功
//readFile("D:/lei_project/qtproject/XMLdemo/books.xml");
readFile(":/xml/books.xml");
//readFile("books.xml")