频道栏目
首页 > 程序开发 > 软件开发 > 其他 > 正文
QT之SAX方法解析XML文件
2018-10-08 11:56:01           
收藏   我要投稿

SAX解析方式会逐行扫描XML文档,当遇到标签时会触发解析处理器,采用事件处理的方式来进行通知,如当读取到如下XML文档时,处理器会一次发出以下事件:

xml:

Gnothi seauton

一次发出事件:

---startDocument()

---startElement("doc")

---startElement("quote")

---characters("Gnothi seauton")

---endElement("quote")

---endElement("doc")

---endDocument()

SAX解析XML的特点:

1、一边读取一边解析,不需要加载进内存,因此速度快、不占用内存,适合解析大XML文档;

2、只能读取XML文档,不能对文档进行增、删、改等操作。

SAX解析XML文档类的封装:

#ifndef XBELHANDLER_H

#define XBELHANDLER_H

#include

#include

class QTreeWidget;

class QTreeWidgetItem;

class XbelHandler : public QXmlDefaultHandler

{

public:

XbelHandler(QTreeWidget *treeWidget);

// 启动 XML 解析

bool readFile(const QString &fileName);

// 解析开始元素

bool startElement(const QString &namespaceURI, const QString &localName,

const QString &qName, const QXmlAttributes &attributes);

// 解析结束元素

bool endElement(const QString &namespaceURI, const QString &localName,

const QString &qName);

// 解析字符数据

bool characters(const QString &str);

// 解析过程中的错误处理

bool fatalError(const QXmlParseException &exception);

QString errorString() const;

private:

// 创建树节点

QTreeWidgetItem *createChildItem(const QString &tagName);

private:

QTreeWidget *treeWidget;

QTreeWidgetItem *item;

QString currentText;

QString errorStr;

QIcon folderIcon;

QIcon otherIcon;

};

#endif

#include "MyXML.h"

#include

#include

#include

XbelHandler::XbelHandler(QTreeWidget *treeWidget)

: QXmlDefaultHandler(),

treeWidget(treeWidget)

{

item = 0;

QStyle *style = treeWidget->style();

folderIcon.addPixmap(style->standardPixmap(QStyle::SP_DirClosedIcon),

QIcon::Normal, QIcon::Off);

folderIcon.addPixmap(style->standardPixmap(QStyle::SP_DirOpenIcon),

QIcon::Normal, QIcon::On);

otherIcon.addPixmap(style->standardPixmap(QStyle::SP_FileIcon));

}

bool XbelHandler::readFile(const QString &fileName)

{

if (fileName.isEmpty())

return false;

treeWidget->clear();

item = 0;

QFile file(fileName);

QXmlInputSource inputSource(&file);

QXmlSimpleReader reader;

reader.setContentHandler(this);

reader.setErrorHandler(this);

return reader.parse(inputSource);

}

// 解析开始元素

bool XbelHandler::startElement(const QString & /* namespaceURI */,

const QString & /* localName */,

const QString &qName,

const QXmlAttributes &attributes)

{

if (qName == "library") {

QString version = attributes.value("Version");

if (!version.isEmpty() && version != "1.0") {

errorStr = QObject::tr("The file is not an XBEL version 1.0 file.");

return false;

}

item = createChildItem(qName);

item->setFlags(item->flags() | Qt::ItemIsEditable);

item->setIcon(0, folderIcon);

item->setText(0, qName);

treeWidget->setItemExpanded(item, true);

} else if (qName == "NumberList") {

item = createChildItem(qName);

item->setFlags(item->flags() | Qt::ItemIsEditable);

item->setIcon(0, folderIcon);

item->setText(0, qName);

treeWidget->setItemExpanded(item, true);

} else if (qName == QString::fromLocal8Bit("Number")) {

item = createChildItem(qName);

item->setFlags(item->flags() | Qt::ItemIsEditable);

item->setIcon(0, otherIcon);

item->setText(0, qName);

}

currentText.clear();

return true;

}

// 解析字符数据

bool XbelHandler::characters(const QString &str)

{

currentText += str;

return true;

}

// 解析结束元素

bool XbelHandler::endElement(const QString & /* namespaceURI */,

const QString & /* localName */,

const QString &qName)

{

if (qName == "NumberList") {

if (item) {

item = item->parent();

}

} else if (qName == QString::fromLocal8Bit("Number")) {

if (item) {

item->setText(1, currentText);

item = item->parent();

}

}

return true;

}

// 解析过程中的错误处理

bool XbelHandler::fatalError(const QXmlParseException &exception)

{

QMessageBox::information(treeWidget->window(), QObject::tr("SAX Parser"),

QObject::tr("Parse error at line %1, column %2:\n"

"%3")

.arg(exception.lineNumber())

.arg(exception.columnNumber())

.arg(exception.message()));

return false;

}

// 返回错误字符串

QString XbelHandler::errorString() const

{

return errorStr;

}

// 创建树节点

QTreeWidgetItem *XbelHandler::createChildItem(const QString &tagName)

{

QTreeWidgetItem *childItem;

if (item) {

childItem = new QTreeWidgetItem(item);

} else {

childItem = new QTreeWidgetItem(treeWidget);

}

//childItem->setData(0, Qt::UserRole, tagName);

return childItem;

}

调用:

#include

#include

void XML::on_btnopen_clicked()

{

QString fileName =

QFileDialog::getOpenFileName(this, tr("Open File"),

QDir::currentPath(),

tr("XBEL Files (*.xbel *.xml)"));

if (fileName.isEmpty())

return;

XbelHandler handler(ui.treeWidget);

if (handler.readFile(fileName))

qDebug() << "File loaded";

}

点击复制链接 与好友分享!回本站首页
上一篇:Fiddler配置及使用总结
下一篇:java:String类的获取功能
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站