在Python中解析XBRL文件

3 投票
2 回答
2700 浏览
提问于 2025-04-18 06:42

我正在做一个 XML 解析器。 我的目标是解析一些不同的 XML 文件,这些文件的前缀和标签是一致的,但命名空间会变化

因此,我尝试了以下几种方法:

  • 直接解析 XML,使用 <prefix:tags> 的形式,而不去处理(替换)前缀和命名空间。前缀在不同的文档中保持不变。
  • 自动加载命名空间,这样就可以用正确的命名空间替换标识符(<prefix:tag>)。
  • 仅仅通过标签解析 XML。

我尝试过使用 xml.etree.ElementTree

我也看过 lxml,但是在 lxml 的 XMLParser 中没有找到任何配置选项可以帮助我,尽管在 这里我看到一个答案,作者建议 lxml 应该能够自动收集命名空间。

有趣的是,parsed_file = etree.XML(file) 这行代码出错了,错误信息是:

lxml.etree.XMLSyntaxError: Start tag expected, '<' not found, line 1, column 1

我想解析的文件的一个例子可以在 这里找到。

2 个回答

2

别太在意前缀,关注完整的命名空间

有时候,人们会关注那些短短的前缀,但其实它们并不是最重要的。前缀只是对完整命名空间的简短引用。例如:

xmlns:trw="http://www.trw.com/20131231"

在 XML 中,这意味着从现在开始,"trw:" 代表完整的命名空间 "http://www.trw.com/20131231"。需要注意的是,这个前缀可以在后面的元素中被重新定义,可能会有完全不同的含义。

另一方面,当你真正关心的是完整的含义时,可以把 "trw:row" 理解为 "{http://www.trw.com/20131231}row"。这个翻译的含义是可靠的,不会因为前缀的变化而改变。

解析引用的 XML

链接 http://edgar.sec.gov/Archives/edgar/data/1267097/000104746914000925/trw-20131231.xml 指向一个 XML 文件,这个文件可以通过 xmlstarlet 验证,并且 lxml 可以解析。

你看到的错误信息是指向流的第一个字符,这意味着你可能在文件中遇到了 BOM 字节,或者你正在尝试读取一个被压缩的 XML 文件,这个文件需要先解压。

lxml 和命名空间

lxml 对命名空间的处理非常好。它允许你使用包含命名空间的 XPath 表达式。不过,控制输出中的命名空间前缀会稍微复杂一些,因为这取决于 xmlns 属性,这些属性是序列化文档的一部分。如果你想修改前缀,必须以某种方式组织这些 xmlns 属性,通常是把它们都移动到根元素。同时,lxml 会跟踪每个元素的完整命名空间,所以在序列化时,它会尊重这个完整名称以及当前有效的前缀。

处理这些 xmlns 属性需要写更多的代码,可以参考 lxml 的文档。

1
items = tree.xpath("*[local-name(.) = 'a_tag_goes_here']")

这个方法有效。不过,我还得手动查看生成的列表 items,才能定义我想要的其他过滤功能。

撰写回答