SAX方式
使用SAX方法来解析XML文档比使用DOM方法要清晰很多,更重要的是它的效率要高很多,不过SAX方法只适用于读取XML文档。
一、包含的基本头文件
#include <QXmlDefaultHandler>
二、基本操作
1.读xml文件
声明一个类MyXml继承QXmlDefaultHandler类,重写
startElement()、endElement()、characters()和fatalError()四个函数;
// 已经解析完一个元素的起始标签
bool MySAX::startElement(const QString &namespaceURI,
const QString &localName,
const QString &qName,
const QXmlAttributes &atts)
// 已经解析完一块字符数据
bool MySAX::characters(const QString &ch)
// 已经解析完一个元素的结束标签
bool MySAX::endElement(const QString &namespaceURI,
const QString &localName,
const QString &qName)
// 错误处理
bool MySAX::fatalError(const QXmlParseException &exception)
定义MyXml的对象 myxml.readxml();
readxml()
{
// 读取文件内容
QXmlInputSource inputSource(&file);
// 建立QXmlSimpleReader对象
QXmlSimpleReader reader;
// 设置内容处理器
reader.setContentHandler(this);
// 设置错误处理器
reader.setErrorHandler(this);
// 解析文件
return reader.parse(inputSource);
}
使用流方式读取xml文件
一、包含头文件
#include <QFile>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
二、基本操作
1.写文件
QFile file("my.xml");
if (!file.open(QFile::WriteOnly | QFile::Text))
{
qDebug() << "Error: cannot open file";
return 1;
}
QXmlStreamWriter stream(&file);
stream.setAutoFormatting(true);
stream.writeStartDocument();
stream.writeStartElement("bookmark");
stream.writeAttribute("href", "http://qt.nokia.com/");
stream.writeTextElement("title", "Qt Home");
stream.writeEndElement();
stream.writeEndDocument();
file.close();
qDebug() << "write finished!";
这里使用了setAutoFormatting(true)函数来自动设置格式,这样会自动换行和添加缩进。
然后使用了writeStartDocument(),该函数会自动添加首行的XML说明
(即<?xmlversion="1.0" encoding="UTF-8"?>),添加元素可以使用writeStartElement(),
不过,这里要注意,一定要在元素的属性、文本等添加完成后,使用writeTextElement()来关闭前一个打开的元素。
在最后使用writeEndDocument()来完成文档的写入。
2.读文件
QXmlStreamReader reader;
// 设置文件,这时会将流设置为初始状态
reader.setDevice(&file);
// 如果没有读到文档结尾,而且没有出现错误
while (!reader.atEnd()) {
// 读取下一个记号,它返回记号的类型
QXmlStreamReader::TokenType type = reader.readNext();
// 下面便根据记号的类型来进行不同的输出
if (type == QXmlStreamReader::StartDocument)
qDebug() << reader.documentEncoding()
<< reader.documentVersion();
if (type == QXmlStreamReader::StartElement) {
qDebug() << "<" << reader.name() << ">";
if (reader.attributes().hasAttribute("id"))
qDebug() << reader.attributes().value("id");
}
if (type == QXmlStreamReader::EndElement)
qDebug() << "</" << reader.name() << ">";
if (type == QXmlStreamReader::Characters
&& !reader.isWhitespace())
qDebug() << reader.text();
}
// 如果读取过程中出现错误,那么输出错误信息
if (reader.hasError()) {
qDebug() << "error: " << reader.errorString();
}
file.close();
可以看到流读取器就是在一个循环中通过使用readNext()来不断读取记号的,
这里可以对不同的记号和不同的内容进行不同的处理,既可以在本函数中进行,也可以在其他函数或者其他类中进行。
使用SAX方法来解析XML文档比使用DOM方法要清晰很多,更重要的是它的效率要高很多,不过SAX方法只适用于读取XML文档。
一、包含的基本头文件
#include <QXmlDefaultHandler>
二、基本操作
1.读xml文件
声明一个类MyXml继承QXmlDefaultHandler类,重写
startElement()、endElement()、characters()和fatalError()四个函数;
// 已经解析完一个元素的起始标签
bool MySAX::startElement(const QString &namespaceURI,
const QString &localName,
const QString &qName,
const QXmlAttributes &atts)
// 已经解析完一块字符数据
bool MySAX::characters(const QString &ch)
// 已经解析完一个元素的结束标签
bool MySAX::endElement(const QString &namespaceURI,
const QString &localName,
const QString &qName)
// 错误处理
bool MySAX::fatalError(const QXmlParseException &exception)
定义MyXml的对象 myxml.readxml();
readxml()
{
// 读取文件内容
QXmlInputSource inputSource(&file);
// 建立QXmlSimpleReader对象
QXmlSimpleReader reader;
// 设置内容处理器
reader.setContentHandler(this);
// 设置错误处理器
reader.setErrorHandler(this);
// 解析文件
return reader.parse(inputSource);
}
使用流方式读取xml文件
从Qt 4.3开始引入了两个新的类来读取和写入XML文档:QXmlStreamReader和QXmlStreamWriter。 QXmlStreamReader类
提供了一个快速的解析器通过一个简单的流API来读取格式良好的XML文档,它是作为Qt的SAX解析器的替代品的身份出现的,因为
它比SAX解析器更快更方便。QXmlStreamReader可以从QIODevice或者QByteArray中读取数据。
流读取器的基本原理就是将XML文档报告为一个记号(tokens)流,这一点与SAX相似,而它们的不同之处在于XML记号被报
告的方式。在SAX中,应用程序必须提供处理器(回调函数)来从解析器获得所谓的XML事件;而对于QXmlStreamReader,是应
用程序代码自身来驱动循环,在需要的时候可以从读取器中一个接一个的拉出记号。这个是通过调用readNext()函数实现的,它可以
读取下一个记号,然后返回一个记号类型,然后可以使用isStartElement()和text()等函数来判断这个记号是否包含我们需要的信息。
使用这种主动拉取记号的方式的最大的好处就是可以构建递归解析器,也就是可以在不同的函数或者类中来处理XML文档中的不同记号。
一、包含头文件
#include <QFile>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
二、基本操作
1.写文件
QFile file("my.xml");
if (!file.open(QFile::WriteOnly | QFile::Text))
{
qDebug() << "Error: cannot open file";
return 1;
}
QXmlStreamWriter stream(&file);
stream.setAutoFormatting(true);
stream.writeStartDocument();
stream.writeStartElement("bookmark");
stream.writeAttribute("href", "http://qt.nokia.com/");
stream.writeTextElement("title", "Qt Home");
stream.writeEndElement();
stream.writeEndDocument();
file.close();
qDebug() << "write finished!";
这里使用了setAutoFormatting(true)函数来自动设置格式,这样会自动换行和添加缩进。
然后使用了writeStartDocument(),该函数会自动添加首行的XML说明
(即<?xmlversion="1.0" encoding="UTF-8"?>),添加元素可以使用writeStartElement(),
不过,这里要注意,一定要在元素的属性、文本等添加完成后,使用writeTextElement()来关闭前一个打开的元素。
在最后使用writeEndDocument()来完成文档的写入。
2.读文件
QXmlStreamReader reader;
// 设置文件,这时会将流设置为初始状态
reader.setDevice(&file);
// 如果没有读到文档结尾,而且没有出现错误
while (!reader.atEnd()) {
// 读取下一个记号,它返回记号的类型
QXmlStreamReader::TokenType type = reader.readNext();
// 下面便根据记号的类型来进行不同的输出
if (type == QXmlStreamReader::StartDocument)
qDebug() << reader.documentEncoding()
<< reader.documentVersion();
if (type == QXmlStreamReader::StartElement) {
qDebug() << "<" << reader.name() << ">";
if (reader.attributes().hasAttribute("id"))
qDebug() << reader.attributes().value("id");
}
if (type == QXmlStreamReader::EndElement)
qDebug() << "</" << reader.name() << ">";
if (type == QXmlStreamReader::Characters
&& !reader.isWhitespace())
qDebug() << reader.text();
}
// 如果读取过程中出现错误,那么输出错误信息
if (reader.hasError()) {
qDebug() << "error: " << reader.errorString();
}
file.close();
可以看到流读取器就是在一个循环中通过使用readNext()来不断读取记号的,
这里可以对不同的记号和不同的内容进行不同的处理,既可以在本函数中进行,也可以在其他函数或者其他类中进行。