python libxml2读取器和XML解析恢复

2024-09-24 00:34:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图让一个阅读器从损坏的XML中恢复过来。在domapi(libxml2.readDoc)中使用libxml2.XML_PARSE_RECOVER选项可以工作,并且可以从实体问题中恢复。在

但是,在reader API中使用这个选项(由于我们正在解析的文档的大小,这一点很重要)不起作用。它只是被困在一个永久的循环中(与读卡器。读()返回-1):

示例代码(带小示例):

import cStringIO
import libxml2

DOC = "<a>some broken & xml</a>"

reader = libxml2.readerForDoc(DOC, "urn:bogus", None, libxml2.XML_PARSE_RECOVER | libxml2.XML_PARSE_NOERROR)

ret = reader.Read()
while ret:
    print 'ret: %d' % ret
    print "node name: ", reader.Name(), reader.NodeType()
    ret = reader.Read()

有什么办法恢复正常吗?在


Tags: import示例readdocparse选项xmlreader
3条回答

考虑使用

您提到您有一个非常大的XML文件,它可能有许多记录,您可以串行处理。每个记录(例如<item>...</item>都有一个开始和结束标记,大概-这些将是您的恢复点。在

In ^{} you provide the reader, the handler, and the input sources。更糟的是,使用这种技术,单个记录将无法恢复。它的设置稍微多了一点,但增量解析格式错误的feed一次记录坏记录可能是最好的方法。在

在日志中,请确保为自己提供足够的信息来重建原始记录,这样您就可以为毫无疑问必须处理的所有情况添加额外的恢复代码(例如,创建一个badrecords\{}.xml,以便手动重新处理)。在

祝你好运。在

我不太确定libxml2绑定的当前状态。甚至libxml2站点也建议改用lxml。在lxml中,解析这棵树并忽略&是很好和干净的:

from cStringIO import StringIO
from lxml import etree

DOC = "<a>some broken & xml</a>"

reader = etree.XMLParser(recover=True)
tree = etree.parse(StringIO(DOC), reader)
print etree.tostring(tree.getroot())

lxml文档中的parsers page详细介绍了如何设置解析器和遍历内容。在

编辑:

如果要增量解析文档,也可以使用XMLparser类,因为它是_FeedParser的子类:

^{pr2}$

xml不是以某种一致的方式破坏的吗?难道没有什么模式可以在解析之前修复xml吗?在

例如,如果错误仅由未转义的和号引起,并且不使用CDATA或处理指令,则可以使用regexp修复它。在

编辑:然后看看python标准库中的sgmllib。beauthulsoup使用它,所以它对您的情况很有用。(BeatifulSoup本身只提供树表示,而不提供事件)。在

相关问题 更多 >