【发布时间】:2015-08-16 07:20:18
【问题描述】:
我正在尝试使用使用前缀的 Python 解析 XML 数据,但并非每个文件都有前缀声明。示例 XML:
<?xml version="1.0" encoding="UTF-8"?>
<item subtype="bla">
<thing>Word</thing>
<abc:thing2>Another Word</abc:thing2>
</item>
我一直在使用 xml.etree.ElementTree 来解析这些文件,但是每当没有正确声明前缀时,ElementTree 就会引发解析错误。 (unbound prefix,就在<abc:thing2> 的开头)
搜索此错误会导致我找到建议我修复命名空间声明的解决方案。但是,我不控制我需要使用的 XML,因此修改输入文件不是一个可行的选择。
搜索命名空间解析通常会导致我提出许多关于以与命名空间无关的方式进行搜索的问题,这不是我所需要的。
我正在寻找一些方法来自动解析这些文件,即使命名空间声明被破坏。我曾想过做以下事情:
- 事先告诉 ElementTree 需要哪些名称空间,因为我知道哪些名称空间会出现。我找到了
register_namespace,但这似乎不起作用。 - 在解析之前读入完整的 DTD,看看是否能解决问题。我找不到使用 ElementTree 的方法。
- 告诉 ElementTree 根本不用考虑命名空间。它不应该导致我的数据出现问题,但我发现没有办法这样做
- 使用其他一些可以处理这个问题的解析库——尽管我不希望安装额外的库。我很难从文档中看出是否有其他人能够解决我的问题。
- 我目前看不到的其他路线?
更新:
在har07让我走上lxml的道路后,我试着看看这是否能让我执行我想到的不同的解决方案,结果会是什么:
- 预先告诉解析器期望什么命名空间:我仍然找不到任何“官方”方法来执行此操作,但在我的搜索中,我发现了以编程方式简单地将必要的声明添加到数据的建议。 (对于不同的编程情况 - 不幸的是我再也找不到链接了)这对我来说似乎非常糟糕,但我还是尝试了。它涉及将数据作为字符串加载,将封闭元素更改为具有正确的
xmlns声明,然后将其交给lxml.etree的fromstring方法。不幸的是,这还需要从字符串中删除对编码声明的所有引用。不过,它确实有效。 - 在解析前读入 DTD:
lxml可以(通过attribute_defaults、dtd_validation或load_dtd),但遗憾的是不能解决命名空间问题。 - 告诉
lxml不要打扰命名空间:可以通过recover选项。不幸的是,这也忽略了可能破坏 XML 的其他方式(有关详细信息,请参阅 Har07 的答案)
【问题讨论】:
标签: python xml parsing namespaces xml-namespaces