2015-01-05 13 views
5

Nếu tôi cố gắng phân tích cú pháp XML bị hỏng, ngoại lệ sẽ hiển thị số dòng. Có cách nào để hiển thị ngữ cảnh XML không?Nhận thông báo lỗi phân tích cú pháp tốt hơn từ ElementTree

Tôi muốn xem các thẻ xml trước và sau phần bị hỏng.

Ví dụ:

import xml.etree.ElementTree as ET 
tree = ET.fromstring('<a><b></a>') 

Ngoại lệ:

Traceback (most recent call last): 
    File "tmp/foo.py", line 2, in <module> 
    tree = ET.fromstring('<a><b></a>') 
    File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1300, in XML 
    parser.feed(text) 
    File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1642, in feed 
    self._raiseerror(v) 
    File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1506, in _raiseerror 
    raise err 
xml.etree.ElementTree.ParseError: mismatched tag: line 1, column 8 

Something như thế này sẽ được tốt đẹp:

ParseError: 
<a><b></a> 
=====^ 

Trả lời

12

Bạn có thể làm cho một hàm helper để làm điều này:

import sys 
import io 
import itertools as IT 
import xml.etree.ElementTree as ET 
PY2 = sys.version_info[0] == 2 
StringIO = io.BytesIO if PY2 else io.StringIO 

def myfromstring(content): 
    try: 
     tree = ET.fromstring(content) 
    except ET.ParseError as err: 
     lineno, column = err.position 
     line = next(IT.islice(StringIO(content), lineno)) 
     caret = '{:=>{}}'.format('^', column) 
     err.msg = '{}\n{}\n{}'.format(err, line, caret) 
     raise 
    return tree 

myfromstring('<a><b></a>') 

mang

xml.etree.ElementTree.ParseError: mismatched tag: line 1, column 8 
<a><b></a> 
=======^ 
+0

up-bỏ phiếu cho sử dụng 'err.position' không biết về điều đó. –

+0

@KobiK: Tôi cũng không biết, nhưng một công cụ nội tâm tốt, như IPython, có ích để khám phá những gì có sẵn trong các đối tượng như 'err'. – unutbu

+0

Cảm ơn bạn rất nhiều. Hoạt động tốt đẹp. – guettli

1

Nó không phải là lựa chọn tốt nhất nhưng thật dễ dàng và đơn giản, bạn có thể chỉ phân tích cú pháp số ParseError Trích xuất dòng và cột rồi sử dụng nó để cho thấy đâu là vấn đề.

import xml.etree.ElementTree as ET 
from xml.etree.ElementTree import ParseError 
my_string = '<a><b><c></b></a>' 
try: 
    tree = ET.fromstring(my_string) 
except ParseError as e: 
    formatted_e = str(e) 
    line = int(formatted_e[formatted_e.find("line ") + 5: formatted_e.find(",")]) 
    column = int(formatted_e[formatted_e.find("column ") + 7:]) 
    split_str = my_string.split("\n") 
    print "{}\n{}^".format(split_str[line - 1], len(split_str[line - 1][0:column])*"-") 

Lưu ý: \n chỉ là ví dụ bạn cần chia nhỏ đúng cách.

Các vấn đề liên quan