QT QXmlStreamReader流处理解析XML

来源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")
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值