Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么ElementTree会引发语法错误?_Python_Xml_Parsing - Fatal编程技术网

Python 为什么ElementTree会引发语法错误?

Python 为什么ElementTree会引发语法错误?,python,xml,parsing,Python,Xml,Parsing,我一直试图用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:

我一直试图用
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
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
从yparse导入分析;分析('file.xml')
文件“C:\Python27\yparse.py”,第10行,在analyze中
对于其中的(电动汽车,电动汽车):
文件“C:\Python27\lib\xml\etree\ElementTree.py”,第1258行,下一行
self.\u parser.feed(数据)
文件“C:\Python27\lib\xml\etree\ElementTree.py”,第1624行,在提要中
自我提升错误(v)
文件“C:\Python27\lib\xml\etree\ElementTree.py”,第1488行,在_raiseerror中
提出错误
ParseError:对无效字符号的引用:第1行,第52459列
结果是确定的,但是,如果一个文件工作,它将始终工作。如果文件失败,它总是失败,并且总是在同一点失败

最奇怪的是,我正在使用跟踪来找出是否有任何格式错误的XML破坏了解析器。然后隔离导致故障的节点。但是,当我创建一个包含该节点及其几个邻居的XML文件时,解析工作正常

这似乎也不是尺寸问题。我成功地解析了更大的文件,没有任何问题

有什么想法吗?

以下是一些想法:

(0)解释“一个文件”和“偶尔”:你真的是说它在相同的文件中有时工作,有时失败吗

对每个失败的文件执行以下操作:

(1) 找出文件中投诉的地方:

text = open("the_file.xml", "rb").read()
err_col = 52459
print repr(text[err_col-50:err_col+100]) # should include the error text
print repr(text[:50]) # show the XML declaration
(2) 将文件提交到基于web的XML验证服务,例如

并编辑您的问题以显示您的发现

更新:以下是说明问题的最小xml文件:

[badcharref.xml]
<a>&#1;</a>

[Python 2.7.1 output]
>>> import xml.etree.ElementTree as ET
>>> it = ET.iterparse(file("badcharref.xml"))
>>> for ev, el in it:
...     print el.tag
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  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
xml.etree.ElementTree.ParseError: reference to invalid character number: line 1, column 3
>>>
输出:

comments.xml
6615405 &#x10;
10205764 &#x00;
10213901 &#x00;
10213936 &#x00;
10214123 &#x00;
13292514 &#x03;
...
155656543 &#x1B;
155656564 &#x1B;
157344876 &#x10;
157722583 &#x10;

posts.xml
7607143 &#x1F;
12982273 &#x1B;
12982282 &#x1B;
12982292 &#x1B;
12982302 &#x1B;
12982310 &#x1B;
16085949 &#x1C;
16085955 &#x1C;
...
36303479 &#x12;
36303494 &#xFFFF; <<=== whoops
38942863 &#x10;
...
785292911 &#x08;
801282472 &#x13;
848911592 &#x0B;
comments.xml
6615405;
10205764和#x00;
10213901和#x00;
10213936�;
10214123和#x00;
13292514和x03;
...
155656543和x1B;
1556564和x1B;
157344876;
157722583;
posts.xml
7607143;
12982273;
12982282;
12982292;
12982302;
12982310;
16085949;
16085955和x1C;
...
36303479;

36303494࿿ 正如@John Machin所建议的,所讨论的文件中确实有可疑的数字实体,尽管错误消息似乎指向了文本中的错误位置。可能是由于流式传输和缓冲的特性,很难报告准确的位置

事实上,所有这些实体都出现在文本中:

set(['&#x08;', '&#x0E;', '&#x1E;', '&#x1C;', '&#x18;', '&#x04;', '&#x0A;', '&#x0C;', '&#x16;', '&#x14;', '&#x06;', '&#x00;', '&#x10;', '&#x02;', '&#x0D;', '&#x1D;', '&#x0F;', '&#x09;', '&#x1B;', '&#x05;', '&#x15;', '&#x01;', '&#x03;'])

大多数是不允许的。看起来这个解析器非常严格,您需要找到另一个不那么严格的解析器,或者预处理XML。

我不确定这是否回答了您的问题,但是如果您想使用元素树引发的ParseError异常,您可以这样做:

except ET.ParseError:
            print("catastrophic failure")
            print("last successful: {0}".format(last))

来源:

我觉得在这里还需要注意的是,您可以很容易地捕捉到错误,避免完全停止程序,只需在函数中使用您稍后已经使用的内容,并放置以下语句:

it = ET.iterparse(file(xml))
在try&except括号内:

try:
    it = ET.iterparse(file(xml))
except:
    print('iterparse error')

当然,这不会修复XML文件或预处理技术,但有助于识别导致错误的文件(如果您正在分析批次)

您必须显示一些有问题的XML。您可能有不好的XML,然后当您编辑它以缩小范围时,它就变成了好的XML。编辑可以做一些鬼鬼祟祟的事情…@nedbatcheld这个文件真的很大,让我很难上传。不过,我确实考虑过这种可能性。因此,我直接使用Python的文件操作函数来提取XML的一部分并将其写入另一个文件。您是否可以显示导致这种情况的任何XML?@Pessimoppotamus:根据您的错误消息,错误只发生在文件中52KB处…@NedBatchelder我正在开发一个XML分块器,该分块器可以生成高达52KB的有效XML分块一定的块大小。我将尝试使用它来生成一个失败的XML并上传它。(0)偶尔意味着“使用某些文件”。但是结果是确定的,如果一个文件有效,它将始终有效。如果一个文件失败,它总是失败,并且总是在同一点失败。(1)我这样做了,我没有发现任何明显的错误。(2) 因为太大,所以无法执行此操作。我怀疑是这样,但在发生错误的文件部分附近没有类似的字符。涉及预处理的解决方案不是一个好主意,同样是因为文件有多大。理想情况下,应该有一种方法让XML解析器优雅地记录错误并继续解析,而不是灾难性地崩溃。我现在受够了。我一会儿回来。希望我能验证我的chunker是否正常工作,然后我会上传一些示例。事实上,这些文件被破坏了。我在解析之前做了一些预处理,结果正如预期的那样。这是一个非常老的问题,有一个公认的答案。如果您不确定是否可以在答案中添加任何内容,则应避免为了回答而回答。
try:
    it = ET.iterparse(file(xml))
except:
    print('iterparse error')