Qt 解析XML方式(二)SAX

一.简介

如果要使用xml解析,需要在 pro 文件中 添加 xml模块

需要用到的类:

  • QXmlInputSource:为QXmlReader子类提供输入数据。
  • QXmlSimpleReader:为XML阅读器提供了一个接口。
  • QXmlAttributes:提供XML属性。
  • QXmlDefaultHandler:提供了所有XML处理程序类的默认实现

采用SAX的方式,SAX解析器根本不创建任何对象,只是在遇到XML文档的各种标签如文档开始、元素开始、文本、元素结束时触发对应的事件,并将XML元素的内容封装成事件传出去。我们负责提供事件监听器来监听这些事件,从而触发相应的事件处理方法,并通过这些事件处理方法实现对XML文档的访问。换句话说,就是边读取边解析

优点:具有占用内存少,效率高等特点。

缺点:不便于随机访问任意节点。

二.示例

sax需要的几个对象:QXmlSimpleReader、QXmlInputSource、QXmlDefaultHandler。它们的关系可以描述为:reader读取source的内容,并使用handler来解析。所以handler是我们关注的重点,我们从QXmlDefaultHandler中派生一个处理类并重写它的处理函数实现xml文件的解析。

例子:解析下面的xml文档



    
        16
        40
        
    
    
        17
        45
        
    

源码:

首先自定义的handler类,实现下面4个方法。

#ifndef WXMLHANDLER_H
#define WXMLHANDLER_H

#include 
#include 

struct People
{
    QString sex;    //性别
    int age;        //年龄
    int height;     //身高
    int weight;     //体重
    QString name;   //姓名
};



class WXMLHandler : public QXmlDefaultHandler
{
public:
    WXMLHandler();

protected:
    bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts);

    bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName);

    bool characters(const QString &ch);

    bool error(const QXmlParseException &exception);

private:
    QString  m_currentTagName;

    QList m_peopleList;
    People m_people;
};

#endif // WXMLHANDLER_H



#include "WXMLHandler.h"
#include 

WXMLHandler::WXMLHandler()
{

}

bool WXMLHandler::startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
{
    if(qName == "INFO")
    {
        m_people.name = atts.value("NAME");
        m_people.height = atts.value("HEIGHT").toInt();
    }
    else if(qName == "WOMAN" || qName == "MAN")
    {
        m_people.sex = qName;
    }
    else
    {
        m_currentTagName = qName;
    }
    return true;
}

bool WXMLHandler::endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
{
    m_currentTagName = "";
    if(qName == "WOMAN" || qName == "MAN")
    {
        m_peopleList.append(m_people);
    }
    else if(qName == "People")
    {
        for(int i = 0; i < m_peopleList.count(); ++i)
        {
            People people = m_peopleList.at(i);
            qDebug()<<"age = "<

调用方法:

    QFile file("test.xml");
    if (!file.open(QIODevice::ReadOnly))
        return;

    QXmlInputSource source(&file);
    QXmlSimpleReader reader;

    WXMLHandler handler;
    reader.setContentHandler(&handler);
    reader.setErrorHandler(&handler);
    reader.parse(source);

你可能感兴趣的:(Qt基础,qt,xml,SAX)