使用python解析lxml:如何使用objectify

Boo*_*d16 2 python xml objectify

我试图在spss文件后面读取xml,我想从etree转向objectify.

如何在下面转换此函数以返回物体对象?我想这样做是因为客观化xml对象对我(作为新手)更容易使用,因为它更加pythonic.

def get_etree(path_file):

    from lxml import etree

    with open(path_file, 'r+') as f:
        xml_text = f.read()     
    recovering_parser = etree.XMLParser(recover=True)    
    xml = etree.parse(StringIO(xml_text), parser=recovering_parser)

    return xml
Run Code Online (Sandbox Code Playgroud)

我失败的尝试:

def get_etree(path_file):

    from lxml import etree, objectify

    with open(path_file, 'r+') as f:
        xml_text = objectify.fromstring(xml)   

    return xml
Run Code Online (Sandbox Code Playgroud)

但我得到这个错误:

lxml.etree.XMLSyntaxError: xmlns:mdm: 'http://www.spss.com/mr/dm/metadatamodel/Arc 3/2000-02-04' is not a valid URI
Run Code Online (Sandbox Code Playgroud)

Tom*_*lak 8

第一个最大的错误是将文件读入字符串并将该字符串提供给XML解析器.

Python将读取文件,无论您的默认文件编码是什么(除非您在调用时指定编码read()),并且该步骤很可能会破坏纯ASCII文件以外的任何其他内容.

XML文件有很多编码,你无法预测它们,你真的不应该对它们做出假设.XML文件通过XML声明解决了这个问题.

<?xml version="1.0" encoding="Windows-1252"?>
Run Code Online (Sandbox Code Playgroud)

在解读文件的其余部分之前,XML解析器将读取该位信息并正确配置.利用该设施.永远不要使用open()和read()用于XML文件.

幸运的是lxml让它变得非常简单:

from lxml import etree, objectify

def get_etree(path_file):
    return etree.parse(path_file, parser=etree.XMLParser(recover=True))

def get_objectify(path_file):
    return objectify.parse(path_file)
Run Code Online (Sandbox Code Playgroud)

和

path = r"/path/to/your.xml"
xml1 = get_etree(path)
xml2 = get_objectify(path)

print xml1   # -> <lxml.etree._ElementTree object at 0x02A7B918>
print xml2   # -> <lxml.etree._ElementTree object at 0x02A7B878>
Run Code Online (Sandbox Code Playgroud)

PS:如果你真的那么认真思考,肯定要使用恢复解析器.XML文件是一种数据结构.如果它被破坏(语法无效,不完整,错误解码,你的名字),你真的想要信任(通过定义未定义)尝试读取它的结果或者你宁愿拒绝它并显示错误消息?

我会做后者.使用恢复解析器可能会在以后导致令人讨厌的运行时错误.