Где ловить исключение в цикле "for"?

У меня есть некоторый код, используемый для анализа XML, который я хочу немного улучшить (в основном для учета искаженных файлов XML).

try:
    import xml.etree.cElementTree as ET
except:
    import xml.etree.ElementTree as ET

context = ET.iterparse("myfile.xml", events=("start", "end"))
context = iter(context)
event, root = context.next()
for event, elem in context:
    if event == 'start' and elem.tag == "hello":
        print("start report")

Он отлично работает с этим действительным XML:

<?xml version="1.0" ?>
<Report name="TEST" xmlns:cm="http://www.nessus.org/cm">
<hello>world</hello>
</Report>

Если я аннулирую XML, удалив последний тег, я получу SyntaxError исключение, которое я хочу поймать для обработки недопустимого XML

След от бега:

Traceback (most recent call last):
  File "/tmp/GetNessusScans/parsereport.py", line 12, in <module>
    for event, elem in context:
  File "<string>", line 68, in __iter__
SyntaxError: no element found: line 4, column 0

Мой вопрос: где я должен разместить try: поймать это исключение?

Мне нужно проанализировать файл линейно из-за его размера, и я понимаю, что for цикл в конечном итоге попадает в точку, где есть отсутствующий тег (или несовпадающий). Я попробовал какой-то экзотический код (except предложение действительно сделает что-то полезное, это всего лишь тест):

try:
    import xml.etree.cElementTree as ET
except:
    import xml.etree.ElementTree as ET

context = ET.iterparse("myfile.xml", events=("start", "end"))
context = iter(context)
event, root = context.next()
try:
    for event, elem in context:
except SyntaxError:
    print("invalid XML")
else:
    # if we hit the description of the scan, save it
    if event == 'start' and elem.tag == "hello":
        print("start report")

но, как я подозревал, это не правильно.

1 ответ

Решение

Вы можете принести весь блок синтаксического анализа в свежий try - except блок. Обоснование заключается в том, что в вашем XML может быть сломан любой тег, а не только последний, и поэтому ошибка может возникнуть в любом месте синтаксического анализа.

try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET
try:
    context = ET.iterparse("myfile.xml", events=("start", "end"))
    context = iter(context)
    event, root = context.next()
    for event, elem in context:
        if event == 'start' and elem.tag == "hello":
            print("start report")
except SyntaxError, ParseError as exc:
    pass
except Exception
    pass
Другие вопросы по тегам