<?xml version="1.0"?>
<root xmlns = "http://default-namespace.org/"
xmlns:py = "http://www.python.org/ns/">
<py:elem1 />
<elem2 xmlns="" />
</root>
StartElementHandler
将为每个元素获取以下字符串:
http://default-namespace.org/ root
http://www.python.org/ns/ elem1
elem2
由于 pyexpat
所使用的 Expat
库的限制,被返回的 xmlparser
实例只能被用来解析单个 XML 文档。 请为每个文档调用 ParserCreate
来提供单独的解析器实例。
The Expat XML ParserExpat 项目的主页。
xmlparser.UseForeignDTD([flag])
调用时将 flag 设为真值(默认)将导致 Expat 调用 ExternalEntityRefHandler
时将所有参数设为 None
以允许加载替代的 DTD。 如果文档不包含文档类型声明,ExternalEntityRefHandler
仍然会被调用,但 StartDoctypeDeclHandler
和 EndDoctypeDeclHandler
将不会被调用。
为 flag 传入假值将将撤消之前传入真值的调用,除此之外没有其他影响。
此方法只能在调用 Parse()
或 ParseFile()
方法之前被调用;在已调用过这两个方法之后调用它会导致引发 ExpatError
且 code
属性被设为 errors.codes[errors.XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING]
。
调用 SetReparseDeferralEnabled(False)
会对安全产生影响,详情见下文;在使用 SetReparseDeferralEnabled
方法之前请务必了解这些后果。
Expat 2.6.0 引入了一种名为“重新解析延迟”的安全机制,这种机制可避免因重新解析大量词元的指数级运行时间而导致的拒绝服务,而是会在默认情况下延迟对未完成词元的重新解析直至达到足够的输入量。 由于这种延迟,已注册的处理器有可能 — 具体取决于推送到 Expat 的输入块大小 — 不会在向解析器推送新输入后立即被调用。 如果希望获得即时反馈并接管防止大量词元因大量词元导致的拒绝服务的责任,可以调用 SetReparseDeferralEnabled(False)
暂时或完全禁用当前 Expat 解析器实例的重新解析延迟。 调用 SetReparseDeferralEnabled(True)
可以再次启用重新解析延迟。
请注意 SetReparseDeferralEnabled()
已作为安全修正被向下移植到一些较早的 CPython 发布版。 如果在运行于多个 Python 版本的代码中要用到 SetReparseDeferralEnabled()
请使用 hasattr()
来检查其可用性。
Added in version 3.12.3.
xmlparser.specified_attributes
如果设为非零整数,解析器将只报告在文档实例中指明的属性而不报告来自属性声明的属性。 设置此属性的应用程序需要特别小心地使用从声明中获得的附加信息以符合 XML 处理程序的行为标准。 默认情况下,该属性为假值;它可以在任何时候被更改。
下列属性包含与 xmlparser
对象遇到的最近发生的错误有关联的值,并且一旦对 Parse()
或 ParseFile()
的调用引发了 xml.parsers.expat.ExpatError
异常就将只包含正确的值。
xmlparser.ErrorByteIndex
错误发生位置的字节索引号。
下列属性包含 xmlparser
对象中关联到当前解析位置的值。 在回调报告解析事件期间它们将指示生成事件的字符序列的第一个字符的位置。 当在回调的外部被调用时,所指示的位置将恰好位于最后的解析事件之后(无论是否存在关联的回调)。
xmlparser.CurrentByteIndex
解析器输入的当前字节索引号。
可被设置的处理器列表。 要在一个 xmlparser
对象 o 上设置处理器,请使用 o.handlername = func
。 handlername 必须从下面的列表中获取,而 func 必须为接受正确数量参数的可调用对象。 所有参数均为字符串,除非另外指明。
xmlparser.XmlDeclHandler(version, encoding, standalone)
当解析 XML 声明时被调用。 XML 声明是 XML 建议适用版本、文档文本的编码格式,以及可选的“独立”声明的(可选)声明。 version 和 encoding 将为字符串,而 standalone 在文档被声明为独立时将为 1
,在文档被声明为非独立时将为 0
,或者在 standalone 短语被省略时则为 -1
。 这仅适用于 Expat 的 1.95.0 或更新版本。
xmlparser.StartDoctypeDeclHandler(doctypeName, systemId, publicId, has_internal_subset)
当 Expat 开始解析文档类型声明 (<!DOCTYPE ...
) 时被调用。 doctypeName 会完全按所显示的被提供。 systemId 和 publicId 形参给出所指定的系统和公有标识符,如果被省略则为 None
。 如果文档包含内部文档声明子集则 has_internal_subset 将为真值。 这要求 Expat 1.2 或更新的版本。
xmlparser.UnparsedEntityDeclHandler(entityName, base, systemId, publicId, notationName)
针对未解析(NDATA)实体声明调用。 此方法仅存在于 Expat 库的 1. 2 版;对于更新的版本,请改用 EntityDeclHandler
。 (下层 Expat 库中的对应函数已被声明为过时。)
xmlparser.EntityDeclHandler(entityName, is_parameter_entity, value, base, systemId, publicId, notationName)
针对所有实体声明被调用。 对于形参和内部实体,value 将为给出实体的声明内容的字符串;对于外部实体将为 None
。 notationName 形参对于已解析实体将为 None
,对于未解析实体则为标注的名称。 如果实体为形参实体则 is_parameter_entity 将为真值而如果为普通实体则为假值(大多数应用程序只需要关注普通实体)。 此方法仅从 1.95.0 版 Expat 库开始才可用。
xmlparser.ExternalEntityRefHandler(context, base, systemId, publicId)
为对外部实体的引用执行调用。 base 为当前的基准,由之前对 SetBase()
的调用设置。 公有和系统标识符 systemId 和 publicId 如果给出则圴为字符串;如果公有标识符未给出,则 publicId 将为 None
。 context 是仅根据以下说明来使用的不透明值。
对于要解析的外部实体,这个处理器必须被实现。 它负责使用 ExternalEntityParserCreate(context)
来创建子解析器,通过适当的回调将其初始化,并对实体进行解析。 这个处理器应当返回一个整数;如果它返回 0
,则解析器将引发 XML_ERROR_EXTERNAL_ENTITY_HANDLING
错误,否则解析将会继续。
如果未提供这个处理器,外部实体会由 DefaultHandler
回调来报告,如果提供了该回调的话。
ExpatError.code
Expat 对于指定错误的内部错误号。 errors.messages
字典会将这些错误号映射到 Expat 的错误消息。 例如:
from xml.parsers.expat import ParserCreate, ExpatError, errors
p = ParserCreate()
try:
p.Parse(some_xml_document)
except ExpatError as err:
print("Error:", errors.messages[err.code])
errors
模块也提供了一些错误消息常量和一个将这些消息映射回错误码的字典 codes
,参见下文。
# 3 处理器函数
def start_element(name, attrs):
print('Start element:', name, attrs)
def end_element(name):
print('End element:', name)
def char_data(data):
print('Character data:', repr(data))
p = xml.parsers.expat.ParserCreate()
p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data
p.Parse("""<?xml version="1.0"?>
<parent id="top"><child1 name="paul">Text goes here</child1>
<child2 name="fred">More text</child2>
</parent>""", 1)
来自这个程序的输出是: