QtXml:QXmlStreamReader

一、描述

QXmlStreamReader 提供了一个简单的流 API 来解析格式良好的 XML。

QXmlStreamReader 的典型用法如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<data info="this is data infomation" editor="张三">
	<website herf="www.baidu.com">
		<title>
			<name>baidu</name>
		</title>
	</website>
	<website herf="www.sohu.com">
		<title>
			<name>sohu</name>
		</title>
	</website>
</data>
int main(int argc, char *argv[])
{
    QFile file("demo.xml");
    if (!file.open(QIODevice::ReadOnly))
        return 0;

    QXmlStreamReader reader(&file);
    while(!reader.atEnd())
    {
        if(reader.isStartElement())
        {
            foreach (const QXmlStreamAttribute & attribute, reader.attributes())
            {
                qDebug()<<attribute.name();
                qDebug()<<attribute.value();
                qDebug()<<endl;
            }
        }
        reader.readNext();
    }
    if (reader.hasError())
    {
          qDebug()<<reader.errorString();
    }

    file.close();
}

 

QXmlStreamReader 在设计上是内存保守的,因为它不会将整个 XML 文档树存储在内存中,而是仅存储当前标记。 此外,它通过将所有字符串数据报告为 QStringRef 而不是真正的 QString 对象来实现这一点。


二、类型成员

1、enum QXmlStreamReader::Error

  • NoError:无错误。
  • CustomError:使用 raiseError() 引发了自定义错误。
  • NotWellFormedError:由于读取的 XML 格式不正确,解析器在内部引发了错误。
  • PrematureEndOfDocumentError:输入流在格式正确的 XML 文档被解析之前结束。
  • UnexpectedElementError:解析器遇到了与预期不同的元素。

2、enum QXmlStreamReader::ReadElementTextBehaviour:此枚举指定了 readElementText() 的行为。

  • ErrorOnUnexpectedElement:引发 UnexpectedElementError 并返回当前遇到子元素时读取的内容。
  • IncludeChildElements:递归地包含子元素中的文本。
  • SkipChildElements:跳过子元素。

3、enum QXmlStreamReader::TokenType:此枚举指定读取器当前读取的类型。

  • NoToken:还没有读到任何东西。
  • Invalid:发生了错误,在 error() 和 errorString() 中报告。
  • StartDocument:在 documentVersion() 中报告 XML 版本号,在 documentEncoding() 中报告 XML 文档中指定的编码。如果文档被声明为独立的,则 isStandaloneDocument() 返回 true。
  • EndDocument:报告文档的结尾。
  • StartElement:使用 namespaceUri() 和 name() 报告元素的开始。 空元素也报告为 StartElement,后跟 EndElement。 属性在 attributes() 中报告,命名空间声明在 namespaceDeclarations() 中。
  • EndElement:使用 namespaceUri() 和 name() 报告元素的结尾。
  • Characters:在 text() 中报告字符。 如果字符都是空白字符,则 isWhitespace() 返回 true。如果字符来自 CDATA 部分,则 isCDATA() 返回 true。
  • Comment:在 text() 中报告注释。
  • DTD:在 text() 中报告 DTD,在 notationDeclarations() 中报告符号声明,在 entityDeclarations() 中报告实体声明。DTD 声明的详细信息在 dtdName()、dtdPublicId() 和 dtdSystemId() 中报告。
  • EntityReference:报告无法解析的实体引用。引用的名称在 name() 中报告,替换文本在 text() 中。
  • ProcessingInstruction:在 processingInstructionTarget() 和 processingInstructionData() 中报告处理指令。

三、属性成员

1、namespaceProcessing : bool:此属性控制流读取器是否处理命名空间。如果启用,读取器处理命名空间,否则不处理。默认情况下,名称空间处理处于启用状态。


四、成员函数

1、QXmlStreamReader(QIODevice *device)

构造函数。

2、void addData(const QByteArray &data)

      void addData(const QString &data)

      void addData(const char *data)

添加更多数据供解析器解析。如果已经设置了设备(setDevice(QIODevice *device)),则不执行任何操作。

    QString xmlData = R"(<?xml version="1.0" encoding="UTF-8"?>
                         <data info="this is data infomation" editor="张三">
                            <website herf="www.baidu.com">
                                <title>
                                    <name>baidu</name>
                                </title>
                            </website>
                         </data>)";

    QXmlStreamReader reader;
    reader.addData(xmlData);

    while(!reader.atEnd())
    {
        if(reader.isStartElement())
        {
            foreach (const QXmlStreamAttribute & attribute, reader.attributes())
            {
                qDebug()<<attribute.name();
                qDebug()<<attribute.value();
                qDebug()<<endl;
            }
        }
        reader.readNext();
    }
    if (reader.hasError())
    {
          qDebug()<<reader.errorString();
    }

3、bool atEnd()

如果读取器一直读取到 XML 文档的结尾,或者发生了 error() 并且读取已中止,则返回 true。 否则,它返回 false。(一旦有更多数据可用,atEnd() 将返回 false)

atEnd() 和hasError() 返回true 并且error() 返回PrematureEndOfDocumentError 时,表示到目前为止XML 已经格式良好,但还没有解析完整的XML 文档。

4、QXmlStreamAttributes attributes()

返回 StartElement 的属性。

5、qint64 characterOffset()

     qint64 columnNumber() / qint64 lineNumber()

返回当前字符偏移量,从 0 开始。

返回当前列号,从 0 开始。 / 返回当前行号,从 1 开始。

6、void clear()

从读取器中删除任何device()或数据,并将其内部状态重置为初始状态。

7、QStringRef documentEncoding()

如果 tokenType() 为 StartDocument,则此函数返回 XML 声明中指定的编码字符串。否则返回空字符串。

8、QStringRef documentVersion()

如果 tokenType() 为 StartDocument,则此函数返回 XML 声明中指定的版本字符串。否则返回空字符串。 

9、QStringRef dtdName()

      QStringRef dtdPublicId()

      QStringRef dtdSystemId()

输出DTD信息。

 

10、bool hasError()

是否发生错误。

11、QStringRef name()

返回 StartElementEndElementEntityReference 的本地名称。

    while(!reader.atEnd())
    {
        if(reader.isStartElement())
        {
            qDebug()<<"isStartElement name"<<reader.name();
        }
        if(reader.isEndElement())
        {
            qDebug()<<"isEndElement name"<<reader.name();
        }

        reader.readNext();
    }

12、QStringRef processingInstructionData() / QStringRef processingInstructionTarget()

处理指令信息。

    while(!reader.atEnd())
    {
        if(reader.isProcessingInstruction())
        {
            qDebug()<<"processingInstructionData:"<<reader.processingInstructionData();
            qDebug()<<"processingInstructionTarget:"<<reader.processingInstructionTarget();
        }
        reader.readNext();
    }

 13、void raiseError(const QString &message = QString())

使用可选的错误消息引发自定义错误。

    int sum{0};
    while(!reader.atEnd())
    {
        if(reader.isStartElement())
        {
            ++sum;
            reader.raiseError(reader.name() + "没有错误");
            if (reader.hasError())
            {
                  qDebug()<<reader.errorString();
            }
        }

        reader.readNext();
    }
    qDebug()<<"sum = "<<sum;

引发错误后解析就停止了。

14、QString readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour = ErrorOnUnexpectedElement)

读取 StartElement 时调用的便利函数。读取直到对应的 EndElement 并返回其间的所有文本。在没有错误的情况下,调用此函数后的当前标记(tokenType())是 EndElement

如果当前标记不是 StartElement,则返回空字符串。

    while(!reader.atEnd())
    {
        if(reader.isStartElement())
        {
            qDebug()<<reader.readElementText();
        }
        reader.readNext();
    }

 

 15、QXmlStreamReader::TokenType readNext()

读取下一个标记并返回其类型。除了一个例外,一旦 readNext() 报告了 error(),就无法进一步读取 XML 流。 然后atEnd()返回true,hasError()返回true,此函数返回QXmlStreamReader::Invalid。

例外情况是 error() 返回 PrematureEndOfDocumentError。当到达其他格式良好的 XML 块的末尾时会报告此错误类型,但该块不代表完整的 XML 文档。在这种情况下,当从 QByteArray 读取流时,可以通过调用 addData() 添加下一个 XML 块来恢复解析,或者在从 device() 读取流时等待更多数据到达。

16、bool readNextStartElement()

读取直到当前元素中的下一个开始元素。到达开始元素时返回 true。当到达结束元素或发生错误时,返回 false。

当前元素是与最近解析的起始元素匹配的元素,但尚未到达其匹配的结束元素。当解析器到达结束元素时,当前元素成为父元素。

当只关心解析 XML 元素时,这是一个便捷的函数。

    while(reader.readNextStartElement())
    {
        if(reader.isStartElement())
        {
            foreach (const QXmlStreamAttribute & attribute, reader.attributes())
            {
                qDebug()<<attribute.name();
                qDebug()<<attribute.value();
                qDebug()<<endl;
            }
        }
        reader.readNext();
    }

17、void setDevice(QIODevice *device)

设置设备。设置设备会将读取器重置为其初始状态。

18、void setEntityExpansionLimit(int limit)

设置单个实体允许扩展到的最大字符数限制。 如果单个实体扩展到超过给定的限制,则文档不被视为格式良好。此属性的默认值为 4096 个字符。

该限制是为了在加载未知 XML 文档时防止 DoS 攻击,否则递归实体扩展可能会耗尽所有可用内存。

19、void skipCurrentElement()

读取到当前元素的结尾,跳过任何子节点。此功能对于跳过未知元素很有用。

  • 10
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值