我需要从XML文件中提取某些数据,但也知道提取的元素在原始XML文件中的位置 - 作为文件开头的字符偏移量,或该行中的行号+位置。
常用的python XML库似乎没有提供任何此类功能。
有一个类似的问题Obtaining position info when parsing HTML in Python通过在html5lib周围编写自定义包装器来解决;但是这个库不适合我,因为特定的数据不是HTML。
是否有任何XML解析器可以保存元素位置信息,或者我是否必须为此进行自己的解析?
答案 0 :(得分:1)
Expat parser 具有此功能。这是一个快速而肮脏的例子:
from xml.parsers.expat import ParserCreate, ExpatError, errors
p = ParserCreate()
def start_element(name, attrs):
print(f"Start element at line {p.CurrentLineNumber}, col. {p.CurrentColumnNumber}, byte {p.CurrentByteIndex}: {name}")
def end_element(name):
print(f"End element at line {p.CurrentLineNumber}, col. {p.CurrentColumnNumber}, byte {p.CurrentByteIndex}:", name)
def char_data(data):
print(f"Character data at line {p.CurrentLineNumber}, col. {p.CurrentColumnNumber}, byte {p.CurrentByteIndex}:", repr(data))
def parse_xml(xml: str):
try:
p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data
p.Parse(xml)
except ExpatError as err:
print("Error:", errors.messages[err.code])
parse_xml("<root>abc <tag>ghi</tag>\n def</root>")
这是这段代码的输出:
Start element at line 1, col. 0, byte 0: root
Character data at line 1, col. 6, byte 6: 'abc '
Start element at line 1, col. 10, byte 10: tag
Character data at line 1, col. 15, byte 15: 'ghi'
End element at line 1, col. 18, byte 18: tag
Character data at line 1, col. 24, byte 24: '\n'
Character data at line 2, col. 0, byte 25: ' def'
End element at line 2, col. 4, byte 29: root
如您所见,它可以打印每个 XML 元素的行号、列号和字节位置。
答案 1 :(得分:0)
我不认为这样的事情存在。大多数解析器首先进行解析(将文本流操作为标记,然后将其解析为树)。到那时,他们通常很好地了解它们在原始流中的位置(这是输出解析错误所必需的)。但是,一旦构建了对象树,这些信息就会被很少使用,并且不再可以访问生成的对象。
一个漂亮而丑陋的黑客(同时!)将标记化XML输入,添加引用原始流位置的“position”属性,使用常规库解析XML并使用此属性( s)稍后用户信息......
告诉我们您是如何做到的!