LXMLを使用して両親の子供の要素にアクセスするためのより多くのPythonic方法はありますか
質問
私は、データを効果的に抽出して使用する方法を頭に導こうとしているXBRLドキュメントを突っ込んでいます。私が苦労してきたことの1つは、コンテキスト情報を正しく使用することを確認することです。以下は、私が遊んでいるドキュメントの1つからのスニペットです(これはMattelの最新の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()]
だから私のリストの子供たちには、私のコンテキストリストの最初のアイテムのすべての子供がいます
子供の1つはエンティティ要素、もう1つはピリオド要素です
今、それぞれの子供には子供があり、エンティティ要素には識別子の子要素があり、期間要素には今朝のようにはるかに複雑になっている瞬間の子要素があります。
実際のデータを正しく評価して動作させるために、コンテキスト要素によって報告されている詳細を知る必要があります。コンテキスト要素の各子供たちをテストしなければならないようです。これらの値を取得するためのより速い効率的な方法はありますか?言い換えれば、いくつかの要素を持ち、すべての子供、孫などを含むデータ構造を作成する方法はありますか?
それらを取得したら、データ辞書の構築を開始し、コンテキストに基づいて特定のエントリにデータ要素を割り当てることができます。したがって、コンテキスト要素を効率的かつ完全に取得することは、私のタスクにとって重要です。
解決
Element-Treeインターフェイスを使用して(LXMLもサポートしています)、 Getiterator 現在の要素にルート化されたサブツリーのすべてのノードを反復します。
それで、 [list(c.getiterator()) for c in contextlist]
あなたが望むリストのリストをあなたに与えます(またはあなたは保持したいかもしれません c
結果のリストでは、後でコンテキストリストを使用してジップしないようにする必要がありません。つまり、タプルのリストを作成します。 [(c, list(c.getiterator())) for c in contextlist]
, 、意図した使用に応じて)。
正確なフォームのリストコンプを渡すことに注意してください [x for x in whatever]
決して意味がありません - 使用 list(whatever)
, 、代わりに、他の反復可能なものをリストに変えること。