xml.etree.ElementTree --- ElementTree XML API¶
Source code: Lib/xml/etree/ElementTree.py
xml.etree.ElementTree モジュールは、XML データの解析と作成を行うシンプルで効率的な API を実装しています。
バージョン 3.3 で変更: このモジュールは利用出来る場合は常に高速な実装を使用します。
バージョン 3.3 で非推奨: このモジュールの別名 xml.etree.cElementTree は非推奨です。
注釈
信頼できないデータや認証されていないデータを解析する必要がある場合は、XML のセキュリティ を参照してください。
チュートリアル¶
xml.etree.ElementTree (略して ET) を使うための短いチュートリアルです。
このモジュールの構成要素や基本的な概念の一部を紹介します。
XML 木構造と要素¶
XML は本質的に階層データ形式で、木構造で表すのが最も自然な方法です。ET はこの目的のために 2 つのクラス - XML 文書全体を木で表す ElementTree および木構造内の単一ノードを表す Element - を持っています。文書全体とのやりとり (ファイルの読み書き) は通常 ElementTree レベルで行います。単一 XML 要素およびその子要素とのやりとりは Element レベルで行います。
XML の解析¶
この節では、架空の XML 文書 country_data.xml をサンプルデータとして使います。
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
ファイルを読み込むことでこのデータをインポートすることが出来ます:
import xml.etree.ElementTree as ET
tree = ET.parse('country_data.xml')
root = tree.getroot()
文字列から直接インポートすることも出来ます:
root = ET.fromstring(country_data_as_string)
fromstring() は XML を文字列から Element に直接パースします。 Element はパースされた木のルート要素です。他のパース関数は ElementTree を作成するかもしれません。ドキュメントをきちんと確認してください。
Element として、root はタグと属性の辞書を持ちます:
>>> root.tag
'data'
>>> root.attrib
{}
さらにイテレート可能な子ノードも持ちます:
>>> for child in root:
... print(child.tag, child.attrib)
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
子ノードは入れ子になっており、インデックスで子ノードを指定してアクセスできます:
>>> root[0][1].text
'2008'
注釈
XML 入力の全ての要素が、パース後の木に要素として含まれる訳ではありません。現在、このモジュールは入力中のいかなる XML コメント、処理命令、ドキュメントタイプ宣言も読み飛ばします。しかし、XML テキストからのパースではなく、このモジュールの API を使用して構築された木には、コメントや処理命令を含むことができ、それらは XML 出力の生成時に含まれます。ドキュメントタイプ宣言は、 XMLParser コンストラクタにカスタムの TreeBuilder インスタンスを渡すことで、アクセスすることができます。
非ブロックパースのためのプル API¶
このモジュールが提供するパース関数のほとんどは、結果を返す前に、ドキュメント全体を読む必要があります。 XMLParser を使用して、インクリメンタルにデータを渡すことは可能ではありますが、それはコールバック対象のメソッドを呼ぶプッシュ API であり、多くの場合、低水準すぎて不便です。ユーザーが望むのは、完全に出来上がった Element オブジェクトを便利に使いながら、操作をブロックすることなく XML のパースをインクリメンタルに行えることです。
これを行うための最も強力なツールは XMLPullParser です。
XML データを取得するためにブロックする読み込みは行わず、XMLPullParser.feed() を呼び出してデータを少しずつ渡します。
解析された XML 要素を取得するには XMLPullParser.read_events() を呼び出します。
以下に例を示します。
>>> parser = ET.XMLPullParser(['start', 'end'])
>>> parser.feed('<mytag>sometext')
>>> list(parser.read_events())
[('start', <Element 'mytag' at 0x7fa66db2be58>)]
>>> parser.feed(' more text</mytag>')
>>> for event, elem in parser.read_events():
... print(event)
... print(elem.tag, 'text=', elem.text)
...
end
mytag text= sometext more text
これの分かりやすい用途は、XML データをソケットから受信したり、ストレージデバイスからインクリメンタルに読み出したりするような、非ブロック式に動作するアプリケーションです。このような場合、ブロッキング読み出しは使用できません。
柔軟性が高いため、単純な用途では XMLPullParser がかえって使いにくいこともあります。
XML データの読み込みでアプリケーションがブロックしても構わず、逐次的な解析は行いたい場合は、iterparse() を検討してください。
どちらのパーザも木を逐次的に構築しますが、逐次的に解放するわけではありません。 文書全体を読み終えるまで、解析したすべての要素が保持されます。 メモリ使用量を抑えるには、不要になったデータを取り除いてください。
処理する要素が大きい場合は、要素を空にすれば十分です。 木のどこにある要素でも使えますが、空にした要素自体は木に残ります。
for event, elem in ET.iterparse(source):
if elem.tag == 'record':
process(elem)
elem.clear()
子要素が大量にある場合は、処理済みの子要素を親要素から削除してください。
for event, elem in ET.iterparse(source, events=('start', 'end')):
if event == 'start' and elem.tag == 'parent':
parent = elem
elif event == 'end' and elem.tag == 'child':
process(elem)
parent.remove(elem)
これらの例はあらゆる場合に使えるものではなく、よくある 2 つの場合の考え方を示したものです。
木がまったく不要なら、代わりに XMLParser とカスタムのターゲットを使って解析してください。
この場合は木を構築しないので、何も削除する必要がありません。
イベントによる 即時の フィードバックが必要な場合は、XMLPullParser.flush() メソッドを呼ぶことで遅延を減らせます。
関連するセキュリティ上の注意を必ず確認してください。
関心ある要素の検索¶
Element は、例えば、Element.iter() などの、配下 (その子ノードや孫ノードなど) の部分木全体を再帰的にイテレートするいくつかの役立つメソッドを持っています:
>>> for neighbor in root.iter('neighbor'):
... print(neighbor.attrib)
...
{'name': 'Austria', 'direction': 'E'}
{'name': 'Switzerland', 'direction': 'W'}
{'name': 'Malaysia', 'direction': 'N'}
{'name': 'Costa Rica', 'direction': 'W'}
{'name': 'Colombia', 'direction': 'E'}
Element.findall() はタグで現在の要素の直接の子要素のみ検索します。 Element.find() は特定のタグで 最初の 子要素を検索し、 Element.text は要素のテキストコンテンツにアクセスします。 Element.get() は要素の属性にアクセスします:
>>> for country in root.findall('country'):
... rank = country.find('rank').text
... name = country.get('name')
... print(name, rank)
...
Liechtenstein 1
Singapore 4
Panama 68
XPath を使用すると、より洗練された方法で、検索したい要素を指定することができます。
XML ファイルの編集¶
ElementTree は XML 文書を構築してファイルに出力する簡単な方法を提供しています。ElementTree.write() メソッドはこの目的に適います。
Element オブジェクトを作成すると、そのフィールドの直接変更 (Element.text など) や、属性の追加および変更 (Element.set() メソッド)、あるいは新しい子ノードの追加 (例えば Element.append() など) によってそれを操作できます。
例えば各 country の rank に 1 を足して、rank 要素に updated 属性を追加したい場合:
>>> for rank in root.iter('rank'):
... new_rank = int(rank.text) + 1
... rank.text = str(new_rank)
... rank.set('updated', 'yes')
...
>>> tree.write('output.xml')
XML はこのようになります:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
Element.remove() を使って要素を削除することが出来ます。例えば rank が 50 より大きい全ての country を削除したい場合:
>>> for country in root.findall('country'):
... # 走査中の削除を避けるため root.findall() を使う
... rank = int(country.find('rank').text)
... if rank > 50:
... root.remove(country)
...
>>> tree.write('output.xml')
Python のリストや辞書と同様、イテレートしながら変更すると問題が起こることがあります。
そのため、この例ではまず root.findall() で一致するすべての要素を集め、その結果のリストをイテレートしています。
XML はこのようになります:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
</data>
XML 文書の構築¶
SubElement() 関数は、与えられた要素に新しい子要素を作成する便利な手段も提供しています:
>>> a = ET.Element('a')
>>> b = ET.SubElement(a, 'b')
>>> c = ET.SubElement(a, 'c')
>>> d = ET.SubElement(c, 'd')
>>> ET.dump(a)
<a><b /><c><d /></c></a>
名前空間のある XML の解析¶
XML 入力が 名前空間 を持っている場合、 prefix:sometag の形式で修飾されたタグと属性が、その prefix が完全な URI で置換された {uri}sometag の形に展開されます。さらに、 デフォルトの XML 名前空間 があると、修飾されていない全てのタグにその完全 URI が前置されます。
ひとつは接頭辞 "fictional" でもうひとつがデフォルト名前空間で提供された、 2 つの名前空間を組み込んだ XML の例をここにお見せします:
<?xml version="1.0"?>
<actors xmlns:fictional="http://characters.example.com"
xmlns="http://people.example.com">
<actor>
<name>John Cleese</name>
<fictional:character>Lancelot</fictional:character>
<fictional:character>Archie Leach</fictional:character>
</actor>
<actor>
<name>Eric Idle</name>
<fictional:character>Sir Robin</fictional:character>
<fictional:character>Gunther</fictional:character>
<fictional:character>Commander Clement</fictional:character>
</actor>
</actors>
この XML の例を、検索し、渡り歩くためのひとつの方法としては、 find() や findall() に渡す xpath で全てのタグや属性に手作業で URI を付けてまわる手があります:
root = fromstring(xml_text)
for actor in root.findall('{http://people.example.com}actor'):
name = actor.find('{http://people.example.com}name')
print(name.text)
for char in actor.findall('{http://characters.example.com}character'):
print(' |-->', char.text)
もっと良い方法があります。接頭辞の辞書を作り、これを検索関数で使うことです:
ns = {'real_person': 'http://people.example.com',
'role': 'http://characters.example.com'}
for actor in root.findall('real_person:actor', ns):
name = actor.find('real_person:name', ns)
print(name.text)
for char in actor.findall('role:character', ns):
print(' |-->', char.text)
どちらのアプローチでも同じ結果です:
John Cleese
|--> Lancelot
|--> Archie Leach
Eric Idle
|--> Sir Robin
|--> Gunther
|--> Commander Clement
XPath サポート¶
このモジュールは木構造内の要素の位置決めのための XPath 式 を限定的にサポートしています。その目指すところは短縮構文のほんの一部だけのサポートであり、XPath エンジンのフルセットは想定していません。
使用例¶
以下はこのモジュールの XPath 機能の一部を紹介する例です。XML の解析 節から XML 文書 countrydata を使用します:
import xml.etree.ElementTree as ET
root = ET.fromstring(countrydata)
# Top-level elements
root.findall(".")
# All 'neighbor' grand-children of 'country' children of the top-level
# elements
root.findall("./country/neighbor")
# Nodes with name='Singapore' that have a 'year' child
root.findall(".//year/..[@name='Singapore']")
# 'year' nodes that are children of nodes with name='Singapore'
root.findall(".//*[@name='Singapore']/year")
# All 'neighbor' nodes that are the second child of their parent
root.findall(".//neighbor[2]")
名前空間を持つ XML では、通常の修飾された {namespace}tag 記法を使います。
# 文書内のすべての Dublin Core の "title" タグ
root.findall(".//{http://purl.org/dc/elements/1.1/}title")
サポートされている XPath 構文¶
操作 |
意味 |
|---|---|
|
指定されたタグを持つすべての子要素を選択します。
例えば バージョン 3.8 で変更: アスタリスクのワイルドカードをサポートしました。 |
|
コメントや処理命令を含む、すべての子要素を選択します。
例えば |
|
現在のノードを選択します。これはパスの先頭に置くことで相対パスであることを示すのに役立ちます。 |
|
現在の要素の下にある全てのレベルの全ての子要素を選択します。例えば、 |
|
親ノードを選択します。パスが開始要素 ( |
|
与えられた属性を持つ全ての要素を選択します。 |
|
与えられた属性が与えられた値を持つ全ての要素を選択します。 値に引用符は含められません。 |
|
与えられた属性が与えられた値を持たない全ての要素を選択します。 値に引用符は含められません。 Added in version 3.10. |
|
|
|
子孫のテキストも含めたテキスト全体が、指定された Added in version 3.7. |
|
子孫のテキストも含めたテキスト全体が、指定された Added in version 3.10. |
|
子孫を含む完全なテキストコンテンツと与えられた |
|
子孫を含む完全なテキストコンテンツと与えられた Added in version 3.10. |
|
与えられた位置にあるすべての要素を選択します。位置は整数 (先頭は 1)、式 |
述語 (角括弧内の式) の前にはタグ名、アスタリスク、あるいはその他の述語がなければなりません。
position 述語の前にはタグ名がなければなりません。
リファレンス¶
関数¶
- xml.etree.ElementTree.canonicalize(xml_data=None, *, out=None, from_file=None, **options)¶
C14N 2.0 変換を行う関数です。
正規化とは、バイト単位の比較やデジタル署名ができるように XML 出力を一定の形式に揃える方法です。 XML のシリアライズ時の自由度を減らし、より制約の強い XML 表現を生成します。 主な制約は、名前空間宣言の配置、属性の順序、無視できる空白に関するものです。
この関数は XML データの文字列 (xml_data)、またはファイルパスやファイル類似オブジェクト (from_file) を入力として受け取り、正規化した形式に変換します。 out にファイルオブジェクトまたはファイル類似オブジェクトが指定されていればそこに書き込み、指定されていなければテキスト文字列として返します。 出力先のファイルに書き込まれるのはバイト列ではなくテキストなので、エンコーディングを
utf-8にしてテキストモードで開いてください。利用例:
xml_data = "<root>...</root>" print(canonicalize(xml_data)) with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file: canonicalize(xml_data, out=out_file) with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file: canonicalize(from_file="inputfile.xml", out=out_file)
設定用の options は次のとおりです。
with_comments: 真にするとコメントを含めます (デフォルトは偽)。
- strip_text: 真にするとテキストの前後の空白を除去します。
(デフォルト: false)
- rewrite_prefixes: 真にすると名前空間の接頭辞を "n{number}" に置き換えます。
(デフォルト: false)
- qname_aware_tags: 修飾名を含むタグの名前の集合。
テキスト中の接頭辞を置き換えます (デフォルトは空)。
- qname_aware_attrs: 修飾名を含む属性の名前の集合。
テキスト中の接頭辞を置き換えます (デフォルトは空)。
exclude_attrs: シリアライズしない属性の名前の集合。
exclude_tags: シリアライズしないタグの名前の集合。
上のオプション一覧で「集合」とあるものには、文字列のコレクションやイテラブルを使えます。 順序は問いません。
Added in version 3.8.
- xml.etree.ElementTree.Comment(text=None)¶
コメント要素のファクトリです。 このファクトリ関数は、標準のシリアライザが XML コメントとしてシリアライズする特別な要素を作成します。 text はコメントの内容を含む文字列です。 コメントを表す要素インスタンスを返します。
XMLParserは、入力に含まれるコメントを読み飛ばし、コメントオブジェクトは作成しません。ElementTreeは、Elementメソッドの 1 つを使用して木内に挿入されたコメントノードのみを含みます。
- xml.etree.ElementTree.dump(elem)¶
要素の木もしくは要素の構造を sys.stdout に出力します。この関数はデバッグ目的のみに使用してください。
出力される形式の正確なところは実装依存です。このバージョンでは、通常の XML ファイルとして出力されます。
elem は要素の木もしくは個別の要素です。
バージョン 3.8 で変更:
dump()関数はユーザーが指定した属性の順序を保持するようになりました。
- xml.etree.ElementTree.fromstring(text, parser=None)¶
文字列定数で与えられた XML 断片を解析します。
XML()と同じです。 text には XML データを含む文字列を指定します。 parser はオプションで、パーザのインスタンスを指定します。指定されなかった場合、標準のXMLParserパーザを使用します。Elementインスタンスを返します。
- xml.etree.ElementTree.fromstringlist(sequence, parser=None)¶
文字列フラグメントのシーケンスから XML ドキュメントを解析します。 sequence は XML データのフラグメントを格納した、リストかその他のシーケンスです。 parser はオプションのパーザインスタンスです。パーザが指定されない場合、標準の
XMLParserパーザが使用されます。Elementインスタンスを返します。Added in version 3.2.
- xml.etree.ElementTree.indent(tree, space=' ', level=0)¶
部分木に空白を追加して、木をインデントで見やすくします。 XML を整形して出力するために使えます。 tree には Element または ElementTree を指定できます。 space はインデントの各レベルに挿入する空白文字列で、デフォルトはスペース 2 個です。 すでにインデントされている木の一部分をインデントする場合は、最初のインデントレベルを level に渡してください。
Added in version 3.9.
- xml.etree.ElementTree.iselement(element)¶
オブジェクトが正当な要素オブジェクトであるかをチェックします。 element は要素インスタンスです。引数が要素オブジェクトの場合
Trueを返します。
- xml.etree.ElementTree.iterparse(source, events=None, parser=None)¶
XML 断片を逐次的に解析して要素の木を構築し、処理中の出来事を利用者に報告します。 source は XML データを含むファイルの名前または file object です。 events は報告するイベントのシーケンスです。 サポートするイベントは文字列の
"start"、"end"、"comment"、"pi"、"start-ns"、"end-ns"です ("ns" のイベントは名前空間の詳細情報を取得するために使います)。 events を省略すると"end"イベントだけを報告します。 parser は省略可能なパーザインスタンスです。 指定しなければ標準のXMLParserパーザを使います。 parser はXMLParserまたはそのサブクラスのインスタンスでなければならず、ターゲットにはデフォルトのTreeBuilderだけを使えます。(event, elem)のペアを返す iterator を返します。 このイテレータにはroot属性があり、source をすべて読み終えた後は、構築された XML の木のルート要素を参照します。 イテレータのclose()メソッドは、source がファイル名の場合に内部のファイルオブジェクトを閉じます。iterparse()は木をインクリメンタルに構築しますが、source (または指定のファイル) でのブロッキング読みを起こします。したがって、ブロッキング読みが許可されないアプリケーションには適しません。完全に非ブロックのパースのためには、XMLPullParserを参照してください。木は逐次的に構築されますが、逐次的には解放されません。 文書全体を読み終えるまで、解析したすべての要素が保持されます。 メモリ使用量を抑える方法は 非ブロックパースのためのプル API を参照してください。
注釈
iterparse()は "start" イベントを発行した時に開始タグの文字 ">" が現れたことだけを保証します。そのため、属性は定義されますが、その時点ではテキストの内容も tail 属性も定義されていません。同じことは子要素にも言えて、その時点ではあるともないとも言えません。全部揃った要素が必要ならば、"end" イベントを探してください。
バージョン 3.4 で非推奨: parser 引数。
バージョン 3.8 で変更: イベント
comment,piが追加されました。バージョン 3.13 で変更:
close()メソッドを追加しました。バージョン 3.15 で変更: イテレータがファイルを開いたのに明示的に閉じられなかった場合、
ResourceWarningを出すようになりました。
- xml.etree.ElementTree.parse(source, parser=None)¶
XML 断片を解析して要素の木にします。 source には XML データを含むファイル名またはファイルオブジェクトを指定します。 parser はオプションでパーザインスタンスを指定します。パーザが指定されない場合、標準の
XMLParserパーザが使用されます。ElementTreeインスタンスを返します。
- xml.etree.ElementTree.ProcessingInstruction(target, text=None)¶
PI 要素のファクトリです。このファクトリ関数は XML の処理命令としてシリアライズされた特別な要素を作成します。target は PI ターゲットを含んだ文字列です。text を指定する場合は PI コンテンツを含む文字列にします。PI を表わす要素インスタンスを返します。
Note that
XMLParserskips over processing instructions in the input instead of creating PI objects for them. AnElementTreewill only contain processing instruction nodes if they have been inserted into to the tree using one of theElementmethods.
- xml.etree.ElementTree.register_namespace(prefix, uri)¶
名前空間の接頭辞を登録します。レジストリはグローバルで、与えられた接頭辞か名前空間 URI のどちらかの既存のマッピングはすべて削除されます。prefix には名前空間の接頭辞を指定します。uri には名前空間の URI を指定します。この名前空間のタグや属性は、可能な限り与えられた接頭辞をつけてシリアライズされます。
Added in version 3.2.
- xml.etree.ElementTree.SubElement(parent, tag, /, attrib={}, **extra)¶
子要素のファクトリです。この関数は要素インスタンスを作成し、それを既存の要素に追加します。
parent は親要素です。 tag は子要素の名前です。 attrib は省略可能な辞書で、要素の属性を格納します。 extra はキーワード引数で指定する追加の属性です。 要素インスタンスを返します。
バージョン 3.15 で変更: attrib に
frozendictも指定できるようになりました。バージョン 3.15 で変更: parent と tag は位置専用引数になりました。
- xml.etree.ElementTree.tostring(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)¶
XML 要素を全ての子要素を含めて表現する文字列を生成します。 element は
Elementのインスタンスです。 encoding [1] は出力エンコーディング(デフォルトは US-ASCII)です。 Unicode 文字列を生成するにはencoding="unicode"を使用してください。 それ以外の場合はバイト列を生成します。 method は"xml","html","text"のいずれか(デフォルトは"xml") です。 xml_declaration, default_namespace, short_empty_elements は、ElementTree.write()での意味と同じ意味を持ちます。 XML データを含んだ (オプションで) エンコードされた文字列を返します。バージョン 3.4 で変更: short_empty_elements 引数を追加しました。
バージョン 3.8 で変更: xml_declaration 引数と default_namespace 引数を追加しました。
バージョン 3.8 で変更:
tostring()関数はユーザーが指定した属性の順序を保持するようになりました。
- xml.etree.ElementTree.tostringlist(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)¶
XML 要素を全ての子要素を含めて表現する文字列を生成します。 element は
Elementのインスタンスです。 encoding [1] は出力エンコーディング(デフォルトは US-ASCII)です。 Unicode 文字列を生成するにはencoding="unicode"を使用してください。 それ以外の場合はバイト列を生成します。 method は"xml","html","text"のいずれか(デフォルトは"xml") です。 xml_declaration, default_namespace, short_empty_elements は、ElementTree.write()での意味と同じ意味を持ちます。 XML データを含んだ (オプションで) エンコードされた文字列のリストを返します。b"".join(tostringlist(element)) == tostring(element)となること以外、特定の順序になる保証はありません。Added in version 3.2.
バージョン 3.4 で変更: short_empty_elements 引数を追加しました。
バージョン 3.8 で変更: xml_declaration 引数と default_namespace 引数を追加しました。
バージョン 3.8 で変更:
tostringlist()関数はユーザーが指定した属性の順序を保持するようになりました。
XInclude サポート¶
このモジュールは、補助モジュール xml.etree.ElementInclude を通じて XInclude ディレクティブ を限定的にサポートします。
木の中の情報に基づいて、部分木やテキスト文字列を要素の木に挿入できます。
使用例¶
次の例は XInclude モジュールの使い方を示します。
現在の文書に XML 文書を取り込むには、{http://www.w3.org/2001/XInclude}include 要素を使い、parse 属性を "xml" に設定し、href 属性で取り込む文書を指定します。
<?xml version="1.0"?>
<document xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="source.xml" parse="xml" />
</document>
デフォルトでは href 属性をファイル名として扱います。 カスタムのローダを使えばこの動作を変更できます。 標準の補助モジュールは XPointer 構文をサポートしないことにも注意してください。
To process this file, load it as usual, and pass the root element to the xml.etree.ElementTree module:
from xml.etree import ElementTree, ElementInclude
tree = ElementTree.parse("document.xml")
root = tree.getroot()
ElementInclude.include(root)
ElementInclude モジュールは {http://www.w3.org/2001/XInclude}include 要素を、source.xml 文書のルート要素で置き換えます。
結果は例えば次のようになります。
<document xmlns:xi="http://www.w3.org/2001/XInclude">
<para>This is a paragraph.</para>
</document>
parse 属性を省略すると、デフォルト値の "xml" を使います。 href 属性は必須です。
テキスト文書を取り込むには、{http://www.w3.org/2001/XInclude}include 要素を使い、parse 属性を "text" に設定します。
<?xml version="1.0"?>
<document xmlns:xi="http://www.w3.org/2001/XInclude">
Copyright (c) <xi:include href="year.txt" parse="text" />.
</document>
結果は例えば次のようになります。
<document xmlns:xi="http://www.w3.org/2001/XInclude">
Copyright (c) 2003.
</document>
リファレンス¶
関数¶
- xml.etree.ElementInclude.default_loader(href, parse, encoding=None)¶
Default loader. This default loader reads an included resource from disk. href is a URL. parse is for parse mode either "xml" or "text". encoding is an optional text encoding. If not given, encoding is
utf-8. Returns the expanded resource. If the parse mode is"xml", this is anElementinstance. If the parse mode is"text", this is a string. If the loader fails, it can returnNoneor raise an exception.
- xml.etree.ElementInclude.include(elem, loader=None, base_url=None, max_depth=6)¶
この関数は elem が指す木の XInclude ディレクティブを、その場で展開します。 elem はルートの
Element、またはそのルートを取得するためのElementTreeインスタンスです。 loader は省略可能なリソースローダです。 省略するとdefault_loader()を使います。 指定する場合はdefault_loader()と同じインターフェースを実装する呼び出し可能オブジェクトでなければなりません。 base_url は元のファイルのベース URL で、取り込むファイルへの相対参照を解決するために使います。 max_depth は再帰的な取り込みの最大深度です。 悪意のある内容によるデータの爆発的な増大のリスクを減らすために制限しています。Noneを渡すと制限を無効にします。バージョン 3.9 で変更: base_url 引数と max_depth 引数を追加しました。
Element オブジェクト¶
- class xml.etree.ElementTree.Element(tag, /, attrib={}, **extra)¶
要素クラスです。 このクラスは Element インターフェースを定義し、そのリファレンス実装を提供します。
tag は要素の名前です。 attrib は省略可能な辞書で、要素の属性を格納します。 extra はキーワード引数で指定する追加の属性です。
要素名と属性の名前や値には、文字列または
QNameインスタンスを使います。 text と tail は文字列またはNoneです。 要素名には、特別な要素に使うComment()やProcessingInstruction()も指定できます。 要素名がNoneの場合は要素自体をシリアライズせず、テキストと子要素だけを書き出し、属性は無視します。 複数の要素を含む断片に利用できます。method="html"の場合は属性値にもNoneを指定でき、checkedのような値のない属性を出力します。 木には他のオブジェクトも格納できますが、シリアライズはできません。バージョン 3.15 で変更: attrib に
frozendictも指定できるようになりました。バージョン 3.15 で変更: tag は位置専用引数になりました。
- tag¶
この要素が表すデータの種類を示す文字列です (言い替えると、要素の型です)。
- text¶
- tail¶
これらの属性は要素に結びつけられた付加的なデータを保持するのに使われます。これらの属性値はたいてい文字列ですが、アプリケーション固有のオブジェクトであって構いません。要素が XML ファイルから作られる場合、 text 属性は要素の開始タグとその最初の子要素または終了タグまでのテキストか、あるいは
Noneを保持し、 tail 属性は要素の終了タグと次のタグまでのテキストか、あるいはNoneを保持します。このような XML データ<a><b>1<c>2<d/>3</c></b>4</a>
の場合、 a 要素は text, tail 属性ともに
None, b 要素は text に"1"で tail に"4", c 要素は text に"2"で tail はNone, d 要素 は text がNoneで tail に"3"をそれぞれ保持します。要素の内側のテキストを収集するためには、
itertext()を参照してください。例えば"".join(element.itertext())のようにします。アプリケーションはこれらの属性に任意のオブジェクトを格納できます。
- attrib¶
要素の属性を保持する辞書です。 attrib の値は常に書き換え可能な Python 辞書ですが、ElementTree の実装によっては別の内部表現を使用し、要求されたときにだけ辞書を作るようにしているかもしれません。そうした実装の利益を享受するために、可能な限り下記の辞書メソッドを通じて使用してください。
以下の辞書風メソッドが要素の属性に対して動作します。
- clear()¶
要素をリセットします。この関数は全ての子要素を削除し、全属性を消去し、テキストとテール属性を
Noneに設定します。
- get(key, default=None)¶
要素の key という名前の属性を取得します。
属性の値、または属性がない場合は default を返します。
- items()¶
要素の属性を (名前, 値) のペアとして返します。
- keys()¶
要素の属性名を返します。
- set(key, value)¶
要素の属性 key に value をセットします。
以下のメソッドは要素の子要素 (副要素) に対して動作します。
- append(subelement)¶
要素 subelement を、要素の子要素の内部リストの末尾に追加します。subelement
Elementでない場合、TypeErrorを送出します。
- extend(subelements)¶
イテラブル subelements に含まれる要素を末尾に追加します。 子要素が
ElementでなければTypeErrorを送出します。Added in version 3.2.
- find(match, namespaces=None)¶
match に一致する最初の子要素を探します。 match はタグ名または パス です。 要素インスタンスまたは
Noneを返します。 namespaces は省略可能なマッピングで、名前空間の接頭辞を完全な名前に対応付けます。 接頭辞として''を渡すと、式の中の接頭辞がないすべてのタグ名を、指定された名前空間に属するものとして扱います。
- findall(match, namespaces=None)¶
タグ名または パス に一致するすべての子要素を探します。 一致するすべての要素を文書内の順序で格納したリストを返します。 namespaces は省略可能なマッピングで、名前空間の接頭辞を完全な名前に対応付けます。 接頭辞として
''を渡すと、式の中の接頭辞がないすべてのタグ名を、指定された名前空間に属するものとして扱います。
- findtext(match, default=None, namespaces=None)¶
match に一致する最初の子要素のテキストを探します。 match はタグ名または パス です。 最初に一致した要素のテキスト内容を返します。 要素が見つからなければ default を返します。 一致した要素にテキストがなければ、空文字列を返すことに注意してください。 namespaces は省略可能なマッピングで、名前空間の接頭辞を完全な名前に対応付けます。 接頭辞として
''を渡すと、式の中の接頭辞がないすべてのタグ名を、指定された名前空間に属するものとして扱います。
- insert(index, subelement)¶
要素内の指定された位置に subelement を挿入します。subelement が
Elementでない場合、TypeErrorを送出します。
- iter(tag=None)¶
現在の要素を根とする木の イテレータ を作成します。イテレータは現在の要素とそれ以下のすべての要素を、文書内での出現順 (深さ優先順) でイテレートします。 tag が
Noneまたは'*'でない場合、与えられたタグに等しいものについてのみイテレータから返されます。イテレート中に木構造が変更された場合の結果は未定義です。Added in version 3.2.
- iterfind(match, namespaces=None)¶
タグ名または パス にマッチするすべての子要素を検索します。マッチしたすべての要素を文書内での出現順で yield するイテレータを返します。namespaces はオプションで、名前空間接頭辞と完全名を対応付けるマップオブジェクトを指定します。
Added in version 3.2.
- itertext()¶
テキストのイテレータを作成します。イテレータは、この要素とすべての子要素を文書上の順序で巡回し、すべての内部のテキストを返します。
Added in version 3.2.
- makeelement(tag, attrib)¶
現在の要素と同じ型の新しい要素オブジェクトを作成します。このメソッドは呼び出さずに、
SubElement()ファクトリ関数を使って下さい。
- remove(subelement)¶
要素から subelement を削除します。find* メソッド群と異なり、このメソッドは要素をインスタンスの同一性で比較します。タグや内容では比較しません。
Elementオブジェクトは以下のシーケンス型のメソッドを、サブ要素を操作するためにサポートします:__delitem__(),__getitem__(),__setitem__(),__len__().注意: 子要素を持たない要素は真偽値の判定で
Falseになります。 Python の将来のリリースでは、子要素の有無によらず、すべての要素がTrueになります。 代わりにlen(elem)やelem is not Noneを明示的に使うことを推奨します。element = root.find('foo') if not element: # 注意! print("element not found, or element has no subelements") if element is None: print("element not found")
バージョン 3.12 で変更: Element の真偽値を判定すると
DeprecationWarningを出します。Python 3.8 より前は、XML 要素の属性を名前順にソートしてからシリアライズすることで、出力の順序を予測可能にしていました。 辞書の順序が保証されるようになったため、Python 3.8 ではこの並べ替えを廃止し、元の解析時やユーザーのコードでの作成時の属性の順序を保持するようにしました。
XML Information Set は属性の順序に意味を持たせないことを明示しているため、一般にユーザーのコードは特定の属性の順序に依存しないようにすべきです。 入力時には、どのような順序でも扱えるようにしてください。 暗号署名やテストデータなど、一定の XML 出力が必要な場合は、
canonicalize()関数で正規化したシリアライズを行えます。正規化した出力は使えないものの、特定の属性の順序で出力したい場合は、望む順序で属性を直接作成するようにしてください。 コードを読む人が想定する順序との食い違いを避けられます。 それが難しい場合は、シリアライズの前に次のような処理を行うと、Element を作成したときとは独立に順序を指定できます。
def reorder_attributes(root): for el in root.iter(): attrib = el.attrib if len(attrib) > 1: # ソートなどで属性の順序を調整する attribs = sorted(attrib.items()) attrib.clear() attrib.update(attribs)
ElementTree オブジェクト¶
- class xml.etree.ElementTree.ElementTree(element=None, file=None)¶
ElementTree ラッパークラスです。このクラスは要素の全階層を表現し、さらに標準 XML との相互変換を追加しています。
element は根要素です。file が指定されている場合、その XML ファイルの内容により木は初期化されます。
- _setroot(element)¶
この木の根要素を置き換えます。従って現在の木の内容は破棄され、与えられた要素が代わりに使われます。注意して使ってください。 element は要素インスタンスです。
- find(match, namespaces=None)¶
Element.find()と同じで、木の根要素を起点とします。
- findall(match, namespaces=None)¶
Element.findall()と同じで、木の根要素を起点とします。
- findtext(match, default=None, namespaces=None)¶
Element.findtext()と同じで、木の根要素を起点とします。
- getroot()¶
この木のルート要素を返します。
- iter(tag=None)¶
根要素に対する、木を巡回するイテレータを返します。イテレータは木のすべての要素に渡ってセクション順にループします。tag は探したいタグです (デフォルトではすべての要素を返します)。
- iterfind(match, namespaces=None)¶
Element.iterfind()と同じで、木の根要素を起点とします。Added in version 3.2.
- parse(source, parser=None)¶
外部の XML 断片をこの要素木に入れます。source にはファイル名か ファイルオブジェクト を指定します。parser はオプションで、パーザインスタンスを指定します。パーザが指定されない場合、標準の
XMLParserパーザが使用されます。断片の根要素を返します。
- write(file, encoding='us-ascii', xml_declaration=None, default_namespace=None, method='xml', *, short_empty_elements=True)¶
要素の木をファイルに XML として書き込みます。 file は、ファイル名または書き込み用に開かれた ファイルオブジェクト です。 encoding [1] は出力エンコーディング(デフォルトは US-ASCII)です。 xml_declaration は、 XML 宣言がファイルに書かれるかどうかを制御します。
Falseの場合は常に書かれず、Trueの場合は常に書かれ、Noneの場合は US-ASCII 、 UTF-8 、 Unicode 以外の場合に書かれます (デフォルトはNoneです)。 default_namespace でデフォルトの XML 名前空間 ("xmlns" 用) を指定します。 method は"xml","html","text"のいずれかです (デフォルトは"xml"です)。 キーワード専用の short_empty_elements 引数は、内容がない要素のフォーマットを制御します。True(既定) の場合、単一の空要素タグとして書かれ、Falseの場合、開始タグと終了タグのペアとして書かれます。出力は引数 encoding によって、文字列 (
str) かバイト列 (bytes) になります。encoding が"unicode"の場合、出力は文字列になり、それ以外ではバイト列になります。file が ファイルオブジェクト の場合、型が衝突する場合があります。文字列をバイト列ファイルへ書き込んだり、その逆を行わないよう注意してください。バージョン 3.4 で変更: short_empty_elements 引数を追加しました。
バージョン 3.8 で変更:
write()メソッドはユーザーが指定した属性の順序を保持するようになりました。
以下はこれから操作する XML ファイルです:
<html>
<head>
<title>Example page</title>
</head>
<body>
<p>Moved to <a href="http://example.org/">example.org</a>
or <a href="http://example.com/">example.com</a>.</p>
</body>
</html>
第 1 段落のすべてのリンクの "target" 属性を変更する例:
>>> from xml.etree.ElementTree import ElementTree
>>> tree = ElementTree()
>>> tree.parse("index.xhtml")
<Element 'html' at 0xb77e6fac>
>>> p = tree.find("body/p") # body 内の最初の p タグを探す
>>> p
<Element 'p' at 0xb77ec26c>
>>> links = list(p.iter("a")) # すべてのリンクのリストを返す
>>> links
[<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>]
>>> for i in links: # 見つかったすべてのリンクをイテレートする
... i.attrib["target"] = "blank"
...
>>> tree.write("output.xhtml")
QName オブジェクト¶
TreeBuilder オブジェクト¶
- class xml.etree.ElementTree.TreeBuilder(element_factory=None, *, comment_factory=None, pi_factory=None, insert_comments=False, insert_pis=False)¶
汎用の要素構造ビルダー。これは start, data, end, comment, pi のメソッド呼び出しの列を整形式の要素構造に変換します。このクラスを使うと、好みの XML 構文解析器、または他の XML に似た形式の構文解析器を使って、要素構造を作り出すことができます。
element_factory を指定する場合は、タグと属性の辞書という 2 つの位置引数を受け取る呼び出し可能オブジェクトでなければなりません。 新しい要素インスタンスを返す必要があります。
comment_factory 関数と pi_factory 関数を指定する場合は、コメントや処理命令を作成する
Comment()関数やProcessingInstruction()関数と同じように動作する必要があります。 指定しなければデフォルトのファクトリを使います。 insert_comments や insert_pis が真の場合は、ルート要素の内側にあるコメントや処理命令を木に挿入します (ルート要素の外側にあるものは挿入しません)。- data(data)¶
現在の要素にテキストを追加します。 data は文字列です。
- end(tag)¶
現在の要素を閉じます。 tag は要素の名前です。閉じられた要素を返します。
- start(tag, attrs)¶
新しい要素を開きます。 tag は要素の名前です。 attrs は要素の属性を保持した辞書です。開かれた要素を返します。
- comment(text)¶
text を内容とするコメントを作成します。
insert_commentsが真なら、木にも追加します。Added in version 3.8.
- pi(target, text)¶
target という名前と text を内容とする処理命令を作成します。
insert_pisが真なら、木にも追加します。Added in version 3.8.
加えて、カスタムの
TreeBuilderオブジェクトは以下のメソッドを提供できます:- doctype(name, pubid, system)¶
文書型宣言を処理します。 name は文書型名です。 pubid は公開識別子、system はシステム識別子です。 デフォルトの
TreeBuilderクラスにはこのメソッドはありません。Added in version 3.2.
- start_ns(prefix, uri)¶
パーザが新しい名前空間宣言に遭遇するたびに、その名前空間を定義する要素の開始を示す
start()コールバックより前に呼び出されます。 prefix はデフォルトの名前空間では''、それ以外では宣言された名前空間の接頭辞です。 uri は名前空間 URI です。Added in version 3.8.
- end_ns(prefix)¶
名前空間の接頭辞の対応付けを宣言した要素の
end()コールバックの後に、スコープを外れた prefix の名前を渡して呼び出されます。Added in version 3.8.
- class xml.etree.ElementTree.C14NWriterTarget(write, *, with_comments=False, strip_text=False, rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None, exclude_attrs=None, exclude_tags=None)¶
A C14N 2.0 writer. Arguments are the same as for the
canonicalize()function. This class does not build a tree but translates the callback events directly into a serialised form using the write function.Added in version 3.8.
XMLParser オブジェクト¶
- class xml.etree.ElementTree.XMLParser(*, target=None, encoding=None)¶
このクラスは、このモジュールの構成要素のうち、低水準のものです。効率的でイベントベースのXMLパースのため、
xml.parsers.expatを使用します。feed()メソッドで XML データをインクリメンタルに受け取り、target オブジェクトのコールバックを呼び出すことで、パースイベントをプッシュ API に変換します。target が省略された場合、標準のTreeBuilderが使用されます。 encoding [1] が指定された場合、このあたいは XML ファイル内で指定されたエンコーディングを上書きします。バージョン 3.8 で変更: 引数が キーワード専用 になりました。 html 引数のサポートを終了しました。
- close()¶
パーザへのデータの提供を完了します。構築中に渡される target の
close()メソッドを呼び出す結果を返します。既定では、これがトップレベルのドキュメント要素になります。
- feed(data)¶
パーザにデータを渡します。 data は文字列またはエンコード済みのデータ (
bytesまたは bytes-like object) です。
- flush()¶
すでに渡されている未解析のデータを解析します。 特に Expat 2.6.0 以降で、フィードバックをより早く得るために使えます。
flush()の実装は、Expat の再解析の延期が有効な場合にこれを一時的に無効化し、再解析を開始します。 再解析の延期を無効にするとセキュリティに影響があります。 詳細はxml.parsers.expat.xmlparser.SetReparseDeferralEnabled()を参照してください。flush()はセキュリティ修正として CPython の一部の過去のリリースにもバックポートされています。 さまざまな Python バージョンで実行するコードから使う場合は、hasattr()で利用可能かどうかを確認してください。Added in version 3.13.
XMLParser.feed()は、開始タグごとに target のstart(tag, attrs_dict)メソッドを、終了タグごとにend(tag)メソッドを呼び出し、データはdata(data)メソッドで処理します。 サポートするその他のコールバックメソッドについてはTreeBuilderクラスを参照してください。XMLParser.close()は target のclose()メソッドを呼び出します。XMLParserは木構造の構築以外にも使えます。 次の例では XML ファイルの最大の深さを数えます。>>> from xml.etree.ElementTree import XMLParser >>> class MaxDepth: # パーザのターゲットオブジェクト ... maxDepth = 0 ... depth = 0 ... def start(self, tag, attrib): # 開始タグごとに呼び出される。 ... self.depth += 1 ... if self.depth > self.maxDepth: ... self.maxDepth = self.depth ... def end(self, tag): # 終了タグごとに呼び出される。 ... self.depth -= 1 ... def data(self, data): ... pass # データを処理する必要はない。 ... def close(self): # すべてのデータを解析すると呼び出される。 ... return self.maxDepth ... >>> target = MaxDepth() >>> parser = XMLParser(target=target) >>> exampleXml = """ ... <a> ... <b> ... </b> ... <b> ... <c> ... <d> ... </d> ... </c> ... </b> ... </a>""" >>> parser.feed(exampleXml) >>> parser.close() 4
XMLPullParser オブジェクト¶
- class xml.etree.ElementTree.XMLPullParser(events=None)¶
非ブロックアプリケーションに適したプルパーザです。入力側の API は
XMLParserのものと似ていますが、コールバックターゲットに呼び出しをプッシュするのではなく、XMLPullParserはパースイベントの内部リストを収集し、ユーザーがそこから読み出すことができます。events は、呼び出し元に報告するイベントのシーケンスです。サポートされているイベントは、文字列の"start","end","comment","pi","start-ns","end-ns"("ns" イベントは、名前空間の詳細情報の取得に使用) です。events が省略された場合、"end"イベントのみが報告されます。- feed(data)¶
指定されたデータをパーザに渡します。 data は文字列またはエンコード済みのデータ (
bytesまたは bytes-like object) です。
- flush()¶
すでに渡されている未解析のデータを解析します。 特に Expat 2.6.0 以降で、フィードバックをより早く得るために使えます。
flush()の実装は、Expat の再解析の延期が有効な場合にこれを一時的に無効化し、再解析を開始します。 再解析の延期を無効にするとセキュリティに影響があります。 詳細はxml.parsers.expat.xmlparser.SetReparseDeferralEnabled()を参照してください。flush()はセキュリティ修正として CPython の一部の過去のリリースにもバックポートされています。 さまざまな Python バージョンで実行するコードから使う場合は、hasattr()で利用可能かどうかを確認してください。Added in version 3.13.
- close()¶
パーザにデータストリームの終了を知らせます。
XMLParser.close()と異なり、このメソッドは常にNoneを返します。 パーザを閉じた時点でまだ取得していないイベントは、その後もread_events()で読み出せます。
- read_events()¶
パーザに渡されたデータ内で発生したイベントのイテレータを返します。 イテレータは
(event, elem)のペアを yield します。 event はイベントの種類を表す文字列 (例えば"end") で、elem はイベントに対応するElementオブジェクト、または以下のようなその他の状況を表す値です。start、end: 現在の Element。comment、pi: 現在のコメントまたは処理命令。start-ns: 宣言された名前空間の対応付けを表すタプル(prefix, uri)。end-ns:None(将来のバージョンでは変わる可能性があります)。
read_events()の前の呼び出しで提供されたイベントは、再度 yield されることはありません。イベントは、イテレータから取得された場合にのみ内部キューから消費されるため、read_events()から取得されたイテレータに対して複数の読み出しを並行して反復的に行うと、予期せぬ結果が引き起こされます。
注釈
XMLPullParserが "start" イベントを発行した時点では、開始タグの ">" を読み取ったことだけが保証されます。 そのため属性は定義されていますが、text 属性と tail 属性の内容はまだ未定義です。 子要素も同様に、その時点では存在する場合と存在しない場合があります。全部揃った要素が必要ならば、"end" イベントを探してください。
Added in version 3.4.
バージョン 3.8 で変更: イベント
comment,piが追加されました。
例外¶
- class xml.etree.ElementTree.ParseError¶
解析に失敗した時、このモジュールの様々なメソッドから送出される XML 解析エラーです。この例外のインスタンスが表す文字列は、ユーザフレンドリなメッセージを含んでいます。その他に、以下の属性も利用できます:
- code¶
expat パーザからの数値エラーコードです。エラーコードの一覧とそれらの意味については、
xml.parsers.expatのドキュメントを参照してください。
- position¶
エラーが発生した場所を示す line と column 番号のタプルです。
脚注