gpt4 book ai didi

python - 在 Python 中解析带有未声明前缀的 XML

转载 作者:太空狗 更新时间:2023-10-29 21:49:47 24 4
gpt4 key购买 nike

我正在尝试使用使用前缀的 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,因此修改输入文件不是一个可行的选择。

搜索命名空间解析通常会导致我提出许多关于以命名空间不可知的方式进行搜索的问题,这不是我需要的。

我正在寻找一些方法来自动解析这些文件,即使 namespace 声明被破坏。我考虑过执行以下操作:

  • 预先告诉 ElementTree 预期的 namespace 是什么,因为我知道哪些 namespace 会出现。我找到了 register_namespace ,但这似乎不起作用。
  • 在解析之前读入完整的 DTD,看看是否能解决问题。我找不到使用 ElementTree 执行此操作的方法。
  • 告诉 ElementTree 根本不用担心 namespace 。它不应该导致我的数据出现问题,但我没有办法做到这一点
  • 使用一些其他可以 处理这个问题的解析库 - 尽管我不想安装额外的库。我很难从文档中看出是否有其他人能够解决我的问题。
  • 我目前没有看到的其他路线?

更新:在 Har07 之后,我走上了 lxml 的道路,我试着看看这是否会让我执行我想到的不同解决方案,结果会是什么:

  • 预先告诉解析器预期的 namespace :我仍然找不到任何“官方”方法来执行此操作,但在我的搜索中,我发现了以编程方式简单地将必要的声明添加到数据的建议。 (对于不同的编程情况——不幸的是我再也找不到链接了)这对我来说似乎非常骇人听闻,但我还是试过了。它涉及将数据作为字符串加载,更改封闭元素以具有正确的 xmlns。声明,然后将其交给 lxml.etreefromstring方法。不幸的是,这还需要从字符串中删除所有对编码声明的引用。不过,它确实有效。
  • 在解析之前读入 DTD:可以使用 lxml (通过 attribute_defaultsdtd_validationload_dtd ),但不幸的是没有解决命名空间问题。
  • 讲述 lxml不用担心 namespace :可能通过 recover选项。不幸的是,这也忽略了 XML 可能被破坏的其他方式(有关详细信息,请参阅 Har07 的回答)

最佳答案

一种可能的方法是使用 ElementTree 兼容库,lxml .例如:

from lxml import etree as ElementTree

xml = """<?xml version="1.0" encoding="UTF-8"?>
<item subtype="bla">
<thing>Word</thing>
<abc:thing2>Another Word</abc:thing2>
</item>"""
parser = ElementTree.XMLParser(recover=True)
tree = ElementTree.fromstring(xml, parser)

thing = tree.xpath("//thing")[0]
print(ElementTree.tostring(thing))

要使用 lxml 解析格式不正确的 XML,您需要做的就是将参数 recover=True 传递给 XMLParser 的构造函数。 lxml 还完全支持 xpath 1.0,这在您需要使用更复杂的条件获取部分 XML 文档时非常有用。

更新:

我不知道 recover=True 选项可以容忍的所有 XML 错误类型。但是除了未绑定(bind)的命名空间前缀之外,我还知道另一种类型的错误:unclosed tag。 lxml 将通过自动添加相应的结束标记来修复 - 而不是忽略 - 未关闭的标记。例如,给定以下损坏的 XML:

xml = """<item subtype="bla">
<thing>Word</thing>
<bad>
<abc:thing2>Another Word</abc:thing2>
</item>"""
parser = ElementTree.XMLParser(recover=True)
tree = ElementTree.fromstring(xml, parser)

print(ElementTree.tostring(tree))

lxml解析后最终输出的XML如下:

<item subtype="bla">
<thing>Word</thing>
<bad>
<abc:thing2>Another Word</abc:thing2>
</bad></item>

关于python - 在 Python 中解析带有未声明前缀的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30597100/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com