class QXmlStreamReader#

QXmlStreamReader 提供了一个简单的流API,用于通过快速解析来读取格式良好的XML。 更多

概要#

方法#

注意

本文档可能包含从 C++ 自动翻译到 Python 的代码片段。我们始终欢迎对代码片段的翻译做出贡献。如果您发现翻译存在问题,也可以通过在 https:/bugreports.qt.io/projects/PYSIDE 上创建工单来告诉我们。

详细说明#

警告

本节包含从 C++ 自动翻译到 Python 的代码片段,可能包含错误。

QXmlStreamReader 提供了一个简单的流式 API,用于解析有效的 XML。它是将整个 XML 加载到 DOM 树(参见 QDomDocument)的一种替代方法。 QXmlStreamReaderQIODevice(参见 setDevice() )读取数据,或者从原始 QByteArray(参见 addData() )读取。

Qt 为写入 XML 提供 QXmlStreamWriter

流读取器的基本概念是报文XML文档为一系列的标记流,类似于SAX。QXmlStreamReader和SAX之间的主要区别在于它们报告XML标记的方式。在SAX中,应用程序必须提供处理程序(回调函数),这些处理程序在解析器方便的时候从解析器接收所谓的XML 事件。而在QXmlStreamReader中,应用程序代码本身驱动循环并且依次从读取器中提取标记,正如它需要它们的时候一样。这是通过调用readNext() 来实现的,此时读取器从输入流中读取直到完成下一个标记,然后返回tokenType()。随后可以使用包括isStartElement()text()等一组方便的函数来检查标记,从而获取读取信息。这种拉取方法的一个大优点是可以构建递归下降解析器,这意味着可以将XML解析代码轻松分解为不同的方法或类。这使得在解析XML时跟踪应用程序自己的状态变得更加容易。

使用QXmlStreamReader的典型循环如下

xml = QXmlStreamReader()
...
while not xml.atEnd():
      xml.readNext()
      ... // do processing

if xml.hasError():
      ... // do error handling

QXmlStreamReader是一个正确的XML 1.0解析器,它不包括外部解析实体。只要没有错误发生,应用程序代码可以保证

  • 流读取器提供的数据满足W3C对于正确结构化XML的标准

  • 标记按照有效顺序提供。

除非QXmlStreamReader引发错误,它保证以下内容

  • 所有标签都被正确嵌套和关闭。

  • 内部实体的引用已用正确的替换文本替换。

  • 属性已根据DTD的内部子集进行了归一化或添加。

  • 除了注释和指令外,StartDocument类型的标记发生在所有其他标记之前。

  • 最多只有一个DOCTYPE元素(类型为DTD的标记)存在。

  • 如果存在,DOCTYPE 将出现在所有其他元素之前,除了 StartDocument、注释和加工指令。

特别是,一旦看到任何类型为 StartElementEndElementCharactersEntityReferenceEndDocument 的令牌,将不再看到类型为 StartDocument 或 DTD 的令牌。如果在输入流中存在且顺序不正确,将引发错误。

注意

令牌类型 CommentProcessingInstruction 可在任何地方出现在流中。

在解析过程中发生错误时,atEnd()hasError() 返回 true,且 error() 返回发生错误的错误信息。函数 errorString()lineNumber()columnNumber()characterOffset() 用于构建适当的错误或警告信息。为了简化应用程序代码,QXmlStreamReader 包含一个 raiseError() 机制,允许您引发自定义错误,这些错误将触发上述描述的错误处理。

QXmlStream 书签示例 阐述了如何使用递归下降技术使用流读取器读取 XML 书签文件(XBEL)。

命名空间#

QXmlStream能够理解和解析XML命名空间。例如,在StartElement 的情况下,namespaceUri() 返回元素所在的命名空间,而 name() 返回元素的 本地 名称。通过 namespaceUri 和名称的组合可以唯一地标识一个元素。如果解析器解析的XML实体中没有声明命名空间前缀,则 namespaceUri 为空。

如果您根据XML规范或根本不使用命名空间解析XML数据,可以使用元素的 qualifiedName() 取代。限定名称是元素的 prefix() 后跟冒号再跟元素的本地 name() 名称——正好与原始XML数据中元素的显现方式一样。由于 namespaceUri 到前缀的映射既不是唯一的也不是通用的,所以对于符合命名空间的XML数据应避免使用 qualifiedName()

为了解析已使用未声明命名空间前缀的独立文档,您可以使用 namespaceProcessing 属性完全关闭命名空间处理。

增量解析#

QXmlStreamReader 是一个增量解析器。它能够处理文档不能一次性解析的情况,因为它是分块到达的(例如,从多个文件或通过网络连接)。当读者在完整文档解析完毕之前用完数据,它将报告一个 PrematureEndOfDocumentError 错误。当有更多数据到来时,无论是通过调用 addData() 还是因为通过网络有更多数据可用 device() ,读者将恢复 PrematureEndOfDocumentError 错误,并在下一个调用 readNext() 时继续解析新的数据。

例如,如果你的应用程序使用网络访问管理器从网络读取数据,你会向管理器发出网络请求并接收网络响应。由于 QNetworkReply 是一个 QIODevice ,你将其 readyRead() 信号连接到自定义槽,例如在 QNetworkAccessManager 的讨论中显示的代码片段中的 slotReadyRead() 。在这个槽中,你使用 readAll() 读取所有可用的数据并将其通过 addData() 传递给 XML 流读取器。然后你调用自定义解析函数,该函数从读取器读取 XML 事件。

性能和内存消耗#

QXmlStreamReader 由于设计上内存保守,因此不会在内存中存储整个 XML 文档树,只存储在报告时当前标记。此外,QXmlStreamReader 避免了将 XML 文档映射到方便和 Qt 风格的 API 所需的许多小字符串分配。它通过将所有字符串数据报告为 QStringView 而不是真实的 QString 对象来实现。在那些对象上的任何 toString() 调用都会返回等效的真实 QString 对象。

class TokenType#

此枚举指定读取器刚刚读取的标记类型。

常量

描述

QXmlStreamReader.NoToken

读取器尚未读取任何内容。

QXmlStreamReader.Invalid

发生错误,已在error()errorString() 中报告。

QXmlStreamReader.StartDocument

读取器在documentVersion() 中报告XML版本号,并在documentEncoding() 中报告XML文档中指定的编码。如果文档声明为独立文档,isStandaloneDocument() 返回 true;否则返回 false

QXmlStreamReader.EndDocument

读取器报告文档的结束。

QXmlStreamReader.StartElement

读取器报告元素的开始,具有 namespaceUri()name() 。空元素也报告为 StartElement,然后直接跟随 EndElement。可以通过调用方便的函数 readElementText() 将所有内容连接到相应的 EndElement。属性在 attributes() 中报告,命名空间声明在 namespaceDeclarations() 中报告。

QXmlStreamReader.EndElement

读取器报告元素的结束,具有 namespaceUri()name()

QXmlStreamReader.Characters

读取器在 text() 中报告字符。如果字符都是空白字符,isWhitespace() 返回 true。如果字符来自 CDATA 部分,isCDATA() 返回 true

QXmlStreamReader.Comment

读者在 text() 方法中报告了一个注释。

QXmlStreamReader.DTD

读者在 text() 方法中报告了一个DTD,在 notationDeclarations() 方法中报告了命名声明,在 entityDeclarations() 方法中报告了实体声明。DTD声明的详细信息在 dtdName()dtdPublicId()dtdSystemId() 方法中报告。

QXmlStreamReader.EntityReference

读者报告了一个无法解析的实体引用。引用的名称在 name() 方法中报告,替换文本在 text() 方法中报告。

QXmlStreamReader.ProcessingInstruction

读者在 processingInstructionTarget()processingInstructionData() 方法中报告了处理指令。

class ReadElementTextBehaviour#

此枚举指定了 readElementText() 的不同行为。

常量

描述

QXmlStreamReader.ErrorOnUnexpectedElement

当遇到子元素时,引发一个 UnexpectedElementError 并返回到目前为止所读取的内容。

QXmlStreamReader.IncludeChildElements

递归包括子元素中的文本。

QXmlStreamReader.SkipChildElements

跳过子元素。

4.6版本新功能。

class Error#

此枚举指定了不同的错误情况

常量

描述

QXmlStreamReader.NoError

没有发生错误。

QXmlStreamReader.CustomError

使用了 raiseError() 方法引发了一个自定义错误。

QXmlStreamReader.NotWellFormedError

解析器由于读取的XML不是良好构造的而在内部引发了错误。

QXmlStreamReader.PrematureEndOfDocumentError

输入流在解析形成良好的XML文档之前已结束。如果流中继续到达更多XML数据,则可以从该错误中恢复,可以通过调用 addData() 或等待它通过 device() 到来。

QXmlStreamReader.UnexpectedElementError

解析器遇到了一个与预期不同的元素或标记。

__init__(data)#
参数:

data – str

创建一个新的流读取器,从中读取 data

注意

在Qt 6.5之前的版本中,此构造函数为 QStringconst char* 进行了重载。

__init__()

构建一个流读取器。

另请参阅

setDevice() addData()

__init__(device)
参数:

deviceQIODevice

创建一个新的流读取器,从中读取 device

另请参阅

setDevice() clear()

addData(data)#
参数:

data – str

为读取器添加更多 data 以供读取。如果读取器有一个 device() ,则此函数不执行任何操作。

注意

在Qt 6.5之前的版本中,此函数为 QStringconst char* 进行了重载。

另请参阅

readNext() clear()

addExtraNamespaceDeclaration(extraNamespaceDeclaration)#
参数:

extraNamespaceDeclarationQXmlStreamNamespaceDeclaration

添加一个extraNamespaceDeclaration。此声明将适用于当前元素的子元素,或者如果该函数在读取任何元素之前被调用,则适用于整个XML文档。

addExtraNamespaceDeclarations(extraNamespaceDeclarations)#
参数:

extraNamespaceDeclarations – QXmlStreamNamespaceDeclaration的列表

根据extraNamespaceDeclarations添加声明向量。

atEnd()#
返回类型::

bool

如果读取器已读取到XML文档的末尾,或者发生错误并终止读取,则返回true。否则,返回false

当atEnd()和hasError()返回true,且error()返回PrematureEndOfDocumentError时,这意味着XML到目前为止格式良好,但尚未解析完整的XML文档。可以通过使用addData()方法向下一次添加XML片段来处理这种情况,如果是从QByteArray读取XML,或者等待更多数据到达,如果是从QIODevice读取。无论哪种方式,一旦可用的数据更多,atEnd()都将再次返回false。

另请参阅

hasError() error() device() atEnd()

attributes()#
返回类型::

QXML流属性集

返回StartElement的属性。

characterOffset()#
返回类型::

int

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

另请参阅

lineNumber() columnNumber()

clear()#

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

另请参阅

addData()

columnNumber()#
返回类型::

int

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

另请参阅

lineNumber() characterOffset()

device()#
返回类型::

QIODevice

返回与QXmlStreamReader 关联的当前设备,如果没有分配设备则返回 None.

另请参阅

setDevice()

documentEncoding()#
返回类型::

str

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

documentVersion()#
返回类型::

str

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

dtdName()#
返回类型::

str

如果tokenType()DTD,则此函数返回DTD的名称。否则返回空字符串。

dtdPublicId()#
返回类型::

str

如果tokenType()DTD,则此函数返回DTD的公共标识符。否则返回空字符串。

dtdSystemId()#
返回类型::

str

如果tokenType()DTD,则此函数返回DTD的系统标识符。否则返回空字符串。

entityDeclarations()#
返回类型::

QXmlStreamEntityDeclaration 对象的列表

如果 tokenType() 等于 DTD ,则此函数返回 DTD 的未解析(外部)实体声明。否则返回空向量。

定义了 QXmlStreamEntityDeclarations 类,表示为 QXmlStreamEntityDeclarationQList

entityExpansionLimit()#
返回类型::

int

返回单个实体可以展开的最大字符数。如果单个实体超出给定限制,则文档不被视为良好格式。

entityResolver()#
返回类型::

QXML流实体解析器

返回实体解析器,如果没有实体解析器则返回 None

另请参阅

setEntityResolver()

error()#
返回类型::

错误

返回当前错误的类型,如果没有错误则返回 NoError

errorString()#
返回类型::

str

返回与 raiseError() 关联的错误信息。

hasError()#
返回类型::

bool

如果发生错误返回 true ,否则返回 false

另请参阅

errorString() error()

hasStandaloneDeclaration()#
返回类型::

bool

如果该文档有显式的独立声明(可以是“yes”或“no”),则返回 true;否则返回 false

如果没有解析XML声明,则该函数返回 false

另请参阅

isStandaloneDocument()

isCDATA()#
返回类型::

bool

如果读取器报告出来自CDATA部分的字符,则返回 true;否则返回 false

另请参阅

isCharacters() text()

isCharacters()#
返回类型::

bool

如果 tokenType() 等于 Characters,则返回 true;否则返回 false

另请参阅

isWhitespace() isCDATA()

isComment()#
返回类型::

bool

如果 tokenType() 等于 Comment,则返回 true;否则返回 false

isDTD()#
返回类型::

bool

如果 tokenType() 等于 DTD,则返回 true;否则返回 false

isEndDocument()#
返回类型::

bool

如果 tokenType() 等于 EndDocument 则返回 true;否则返回 false

isEndElement()#
返回类型::

bool

如果 tokenType() 等于 EndElement 则返回 true;否则返回 false

isEntityReference()#
返回类型::

bool

如果 tokenType() 等于 EntityReference 则返回 true;否则返回 false

isProcessingInstruction()#
返回类型::

bool

如果 tokenType() 等于 ProcessingInstruction 则返回 true;否则返回 false

isStandaloneDocument()#
返回类型::

bool

如果此文档在XML声明中已声明为独立文档,则返回 true;否则返回 false

如果没有解析XML声明,则该函数返回 false

isStartDocument()#
返回类型::

bool

如果 tokenType() 等于 StartDocument 则返回 true;否则返回 false

isStartElement()#
返回类型::

bool

如果 tokenType() 等于 StartElement ,则返回 true;否则返回 false

isWhitespace()#
返回类型::

bool

如果读取器报告了只包含空白字符的字符,则返回 true;否则返回 false

另请参阅

isCharacters() text()

lineNumber()#
返回类型::

int

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

name()#
返回类型::

str

返回一个 StartElementEndElement ,或者一个 EntityReference 的局部名称。

namespaceDeclarations()#
返回类型::

一个 QXmlStreamNamespaceDeclaration 列表

如果 tokenType()StartElement ,则此函数返回元素的命名空间声明。否则返回一个空向量。

定义 QXmlStreamNamespaceDeclarations 类为 QXmlStreamNamespaceDeclarationQList

namespaceProcessing()#
返回类型::

bool

namespaceUri()#
返回类型::

str

返回StartElementEndElement 的namespaceUri。

另请参阅

name() qualifiedName()

notationDeclarations()#
返回类型::

QXmlStreamNotationDeclaration 的列表。

如果tokenType()DTD,则此函数返回DTD的notation声明;否则返回空向量。

QXmlStreamNotationDeclarations 类定义为 QListQXmlStreamNotationDeclaration

prefix()#
返回类型::

str

返回StartElementEndElement 的前缀。

另请参阅

name() qualifiedName()

processingInstructionData()#
返回类型::

str

返回ProcessingInstruction 的数据。

processingInstructionTarget()#
返回类型::

str

返回ProcessingInstruction 的目标。

qualifiedName()#
返回类型::

str

返回StartElementEndElement 的限定名称;

合格名称是XML数据中元素的原始名称。它由命名空间前缀、冒号和元素的本地名组成。由于命名空间前缀不唯一(相同的名称空间可以指向不同的命名空间,不同的名称空间可以指向相同的命名空间),因此您不应使用qualifiedName(),而应使用解析后的namespaceUri()以及属性的本地name()

raiseError([message=""])#
参数:

message – str

抛出一个带有可选错误信息的自定义错误。

另请参阅

error() errorString()

readElementText([behaviour=QXmlStreamReader.ReadElementTextBehaviour.ErrorOnUnexpectedElement])#
参数:

behaviourReadElementTextBehaviour

返回类型::

str

当读取到StartElement时调用的便利函数。读取到相应的EndElement并返回之间所有文本。如果没有错误,调用此函数后的当前标记(见tokenType())是EndElement

该函数在读取到CharactersEntityReference标记时,将调用text()函数拼接文本,但会跳过ProcessingInstructionComment。如果在当前标记不是StartElement时,将返回一个空字符串。

behaviour定义了在读取到EndElement之前遇到其他内容的处理方式。该函数可以从子元素中包含文本(例如在HTML中很有用),忽略子元素,或者抛出一个UnexpectedElementError错误并返回读取到的内容(默认选项)。

readNext()#
返回类型::

标记类型

读取下一个标记并返回其类型。

在报告错误error()后,如果调用readNext(),进一步读取XML流将不再可能。此时,atEnd()返回truehasError()返回true,并返回Invalid

error() 返回 PrematureEndOfDocumentError 时,则发生异常。此错误会在达到其他正常形成的XML片段的末尾时报告,但该片段并不代表完整的XML文档。在这种情况下,可以通过调用 addData() 以添加下一个XML片段来重新启动解析,此时流是从一个 QByteArray 中读取,或者等待更多数据到达时从 device() 中读取。

另请参阅

tokenType() tokenString()

readNextStartElement()#
返回类型::

bool

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

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

这是一个当您只关注解析XML元素时的便利函数。在 QXmlStream Bookmarks Example 中广泛使用了此函数。

另请参阅

readNext()

setDevice(device)#
参数:

deviceQIODevice

将当前设备设置为 device。设置设备将流重置为其初始状态。

另请参阅

device() clear()

setEntityExpansionLimit(limit)#
参数:

limit – int

将单个实体可扩展的最大字符数设置为 limit。如果单个实体扩展超过给定限制,则文档不被认为是有良好形成的。

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

此属性的默认值为4096个字符。

另请参阅

entityExpansionLimit

setEntityResolver(resolver)#
参数:

解析器QXmlStreamEntityResolver

resolver 设置为新的 entityResolver() .

流读取器不拥有解析器。确保解析器在整个流读取器对象的生命周期内有效,或者直到另一个解析器或 None 被设置,这是调用者的责任。

另请参阅

entityResolver()

setNamespaceProcessing(arg__1)#
参数:

arg__1 – 布尔值

另请参阅

namespaceProcessing()

skipCurrentElement()#

读取到当前元素结束,跳过任何子节点。此函数对于跳过未知元素很有用。

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

text()#
返回类型::

str

返回 CharactersCommentDTDEntityReference 的文本。

tokenString()#
返回类型::

str

以字符串形式返回读取器的当前令牌。

另请参阅

tokenType()

tokenType()#
返回类型::

标记类型

返回当前令牌的类型。

当前标记也可以使用以下便利函数进行查询:isStartDocument()isEndDocument()isStartElement()isEndElement()isCharacters()isComment()isDTD()isEntityReference()isProcessingInstruction()

另请参阅

tokenString()