是否有更pythonic的方式来使用lxml访问父母的子元素

时间:2010-06-24 01:21:30

标签: python lxml xbrl

我正在寻找XBRL文档,试图了解如何有效地提取和使用数据。我一直在努力的一件事是确保我正确使用上下文信息。下面是我正在播放的一个文件的片段(这是来自美泰最新的10-K)

我希望能够有效地收集上下文键值对,因为它们对于帮助对齐“真实”数据非常重要'以下是上下文元素的示例

- <context id="eol_PE6050----0910-K0010_STD_0_20091231_0">
  - <entity>
     <identifier scheme="http://www.sec.gov/CIK">0000063276</identifier> 
   </entity>
  - <period>
   <instant>2009-12-31</instant> 
   </period>
   </context>

当我开始这个时,我认为如果有一个父子关系,我应该能够直接通过将方法(?)应用于父级来获取所有孩子的属性,键,值和文本。但孩子们保留了他们的独立性,尽管他们可以从父母那里找到。我的意思是,如果孩子们有属性,键,值和/或文本,那么这些构造不能直接从父级访问,而是必须确定/识别子级,并从子级访问所需的数据或元数据。

我不完全确定为什么这段代码是一个很好的起点:

 from lxml import etree
 test_tree=etree.parse(r'c:\temp\test_xml\mat-20091231.xml')
 tree_list=[p for p in test_tree.getiterator() 

所以我的tree_list是确定存在于我的xml文件中的元素列表
因为我的tree_list中只有664个项目,所以我做了一个非常糟糕的假设,即父项中的所有元素都包含在父项中,所以我不断尝试通过引用这些元素(不是它们的子项)来访问实体,句点和瞬间

for each in tree_list:
    if 'context' in each.tag:
        contextlist.append(each)

那就是我继续对上下文列表中的项目应用不同的方法,并且非常沮丧。最后,当我写出问题时,我试图找到一些帮助,找出哪种方法可以给我实体和期间我决定尝试

children=[c for c in contextlist[0].iterchildren()]

所以我的列表子项包含了我的上下文列表中第一项的所有子项

其中一个子元素是实体元素,另一个是句点元素

现在,应该是每个子节点都有一个子节点,实体元素具有标识符子元素,而period元素具有一个即时子元素 这比今天早上看起来要复杂得多。

我必须知道上下文元素报告的详细信息,以正确评估和操作实际数据。看来我必须测试上下文元素的每个子元素是否有更快更有效的方法来获取这些值?重新说明,是否有办法获得一些元素并创建一个包含所有子元素和孙子元素的数据结构,而无需进行大量的try else语句

有了它们,我就可以开始构建数据字典,并根据上下文将数据元素分配给特定条目。因此,有效和完整地获取上下文元素对我的任务至关重要。

1 个答案:

答案 0 :(得分:3)

使用元素树接口(lxml也支持),getiterator遍历以当前元素为根的子树中的所有节点。

因此,[list(c.getiterator()) for c in contextlist]会为您提供所需的列表列表(或者您可能希望在结果列表中保留c,以避免以后必须使用上下文列表将其压缩,即直接列出元组[(c, list(c.getiterator())) for c in contextlist],取决于您的预期用途。)

请注意,确切形式[x for x in whatever]的listcomp从来没有多大意义 - 请使用list(whatever)将其他任何可迭代变为列表。