2015-09-16 7 views
7

Python ElementTree APIの設計上の意思決定にはちょっと混乱しています。これらは多少恣意的に見えるので、これらの決定に何らかの論理があるかどうかを確認したいと思いますそれとも、それらがほんの少しだけアドホックであるならば、Python ElementTree:ElementTree vsRoot要素

一般的に、ElementTreeを生成する2つの方法があります.1つは、ファイルやその他のI/Oストリームのような、ある種のソースストリーム経由です。これは、parse()関数またはElementTree.parse()クラスメソッドによって実現されます。

もう1つの方法は、XMLを文字列オブジェクトから直接ロードすることです。これはfromstring()機能を介して行うことができます。

大丈夫です。さて、私はこれらの関数が基本的に同じであると思います。その2つの関数の違いは、基本的には入力のソースです(ファイルまたはストリームオブジェクトを取り、もう一方はプレーンストリングを取ります)。何らかの理由でparse()関数がElementTreeオブジェクトを返しますが、fromstring()関数はElementオブジェクトを返します。違いは基本的にElementオブジェクトがXMLツリーのルート要素であるのに対し、ElementTreeオブジェクトはいくつかの追加機能を提供するルート要素の周りの「ラッパー」の一種です。 を呼び出すことによって、ElementTreeオブジェクトからいつでもルート要素を取得できます。

まだ、私はこの区別があるのは混乱しています。 fromstring()はルート要素を直接返しますが、parse()ElementTreeオブジェクトを返します。この区別の後ろにいくつかの論理がありますか?

+1

を書くことは簡単ですので、 'ElementTree'のAPIは、時にはいくつかの本当に奇妙な意思決定を持っており、これはその一つです。 – gsnedders

+0

私はlxmlで動作し、apiは同じです。私もこれらの質問に対する答えを知りたいです。私はラッパーレベルで物事を維持する傾向があるが、私は理由を知らない。 –

+1

ElementTreeにはElementよりも多くの機能があります(特に 'write()')。私は、これらの要素がElementに提供できないと言っているわけではありませんが、それは大きな違いです。 'fromstring()'は、要素のみを与えることで、ツリーの変更や書き込みを効果的に防ぎます。 – remram

答えて

0

私はコメントのremramと同じだと思っています。parseは、ファイルの場所またはファイルオブジェクトを取得し、その情報を保持して、追加のユーティリティを提供できるので、本当に役に立ちます。 構文解析がETオブジェクトを返さなかった場合、ETオブジェクトがデフォルトで持っているヘルパー関数に手作業で戻すために、ソースとその他のものをよりよく追跡する必要があります。ファイルとは対照的に、定義上の文字列には、同じ種類の情報が付属していないので、同じユーティリティを作成することはできません(そうでなければ、ET.parsefromstring()メソッドがあります)。 ETオブジェクトを返します)。

私は、これがまた解析代わりET.fromfile()のを命名されている方法の背後にあるロジックである疑いがある:私は、同じオブジェクト型がをfromstring FROMFILEから返されることを期待することができますが、う私はの解析をから期待しています(私はETを使い始めて以来長い時間がかかりました。それを確認する方法はありませんが、それは私の気持ちです)。

Remramは、私がドキュメントを理解しているように、実用的なメソッドを要素に置くことについて提起しましたが、実装に関しては非常に統一されています。人々は「ルート要素」について話しますが、ツリーのルートにある要素は、そのクラスの属性とメソッドの観点から文字通り他のすべての要素と同じです。私が知る限り、Elementsは親が誰であるかを知りません。これはこの統一性をサポートする可能性が高いです。それ以外の場合は、 "ルート"要素(親を持たない)を実装したり、下位要素を再親和するコードがさらに存在する可能性があります。 Elementクラスのシンプルさは、その好意で大きく働いているようです。ですから、同じツリー(または同様のもの)内に異なる出力ファイルを持つ4つの要素に関する何らかの混乱はないはずです。

コード内でモジュールを実装する場合、スクリプトはある時点、ある方法でファイルを入力として認識する必要があります(そうでなければ、ファイルをfromstring)。したがって、の出力がの場合、ElementTreeがElementであると想定され、そのように処理されるような予期しないような状況が発生しないはずです(もちろん、構文解析が実装されていない限り何がの解析でしたか、それはちょうど私にとって貧しい習慣のようです)。

3

美しいの答えは、この古いdiscussionから来ている:

念のために:フレドリック[ElementTreeののクリエーター]は、実際に設計 「癖」は考慮されません。彼はさまざまなユースケースに合わせて設計されていると主張しています。 parse()は通常、完全な文書 (ElementTreeオブジェクトとしてETで表現されます)、fromstring()および (特に、 'literal wrapper' XML()は文字列の解析に使用されます)を解析します。 which ?)には、しばしばXMLフラグメントのみが含まれます。フラグメントを使用すると、 は通常、別の ツリーに挿入するなどの作業を続行したいので、ほとんどの場合、最上位の要素が必要です。

そして:

なぜこれを行うための唯一の方法をet.parseされていませんか?なぜXMLまたはfromstringを持っているのですか ?

まあ、使用例。それはだからXMLは、()、()fromstringの別名である = XML XMLリテラルの

section.append(段落)( 'A Zへ')

セクションを記述するのに便利(とも読めます)ソースコードです。あなたはどんな ソースから得た文字列からの断片を解析したい場合 、それは正確に機能していると表現するのは簡単ですので、あなたが解析したい場合)(fromstringは

el = fromstring(some_string) 

のように、そこにありますファイルまたはファイルのようなオブジェクトからのドキュメントの場合は、 parse()を使用します。 3つのユースケース、3つの機能。文字列から文書を解析 の第四ユースケースは、独自の機能、 を持っていない、それは正直なところ

tree = parse(BytesIO(some_byte_string))