我一直在尝试分析一个文件,其中包含xml.etree.ElementTree
:
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import ParseError
def analyze(xml):
it = ET.iterparse(file(xml))
count = 0
last = None
try:
for (ev, el) in it:
count += 1
last = el
except ParseError:
print("catastrophic failure")
print("last successful: {0}".format(last))
print('count: {0}'.format(count))
这当然是我的代码的简化版本,但这足以破坏我的程序。如果删除try catch块,则某些文件会出现此错误:
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
from yparse import analyze; analyze('file.xml')
File "C:\Python27\yparse.py", line 10, in analyze
for (ev, el) in it:
File "C:\Python27\lib\xml\etree\ElementTree.py", line 1258, in next
self._parser.feed(data)
File "C:\Python27\lib\xml\etree\ElementTree.py", line 1624, in feed
self._raiseerror(v)
File "C:\Python27\lib\xml\etree\ElementTree.py", line 1488, in _raiseerror
raise err
ParseError: reference to invalid character number: line 1, column 52459
结果是确定的,但如果一个文件工作,它将永远工作。如果一个文件失败了,它总是失败并且总是在同一点上失败。
最奇怪的是,我正在使用跟踪来找出是否有任何格式错误的XML正在破坏解析器。然后隔离导致故障的节点。但是,当我创建一个包含该节点及其几个邻居的XML文件时,解析就可以工作了!
这看起来也不是尺寸问题。我已经成功地解析了更大的文件,没有任何问题。
有什么想法吗?
正如@John Machin所建议的,所讨论的文件中确实有可疑的数字实体,尽管错误消息似乎指向了文本中的错误位置。或许流媒体的特性和缓冲使得报告准确的位置变得困难。
事实上,所有这些实体都出现在文本中:
大多数是不允许的。看起来这个解析器相当严格,您需要找到另一个不那么严格的解析器,或者预处理XML。
我不确定这是否回答了您的问题,但是如果您想对元素树引发的ParseError使用异常,您可以这样做:
来源:http://effbot.org/zone/elementtree-13-intro.htm
以下是一些想法:
(0)解释“一个文件”和“偶尔”:你真的是说它有时工作,有时失败与相同的文件?
对每个失败的文件执行以下操作:
(1)找出文件中抱怨的地方:
(2)将文件放入基于web的XML验证服务,例如http://www.validome.org/xml/或http://validator.aborla.net/
编辑你的问题来展示你的发现。
更新:下面是说明您的问题的最小xml文件:
并非所有有效的Unicode字符都在XML中有效。请参阅XML 1.0 Specification。
您可能希望使用诸如
r'&#([0-9]+);'
和r'&#x([0-9A-Fa-f]+);'
之类的正则表达式检查文件,将匹配的文本转换为int序数,并检查规范中的有效列表,即#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
。。。或者数字字符引用在语法上无效,例如没有被
;
,&#not-a-digit
等终止更新2我错了,ElementTree错误消息中的数字正在计算Unicode代码点,而不是字节。请参阅下面的代码和在两个错误文件上运行代码的输出片段。
输出:
相关问题 更多 >
编程相关推荐