Python 2.0 以降では、Document Object Model インタフェース (DOM API) の最小の実装として、xml.dom.minidom が搭載されています。 DOM 標準の API を使って操作する必要のない場合は、よりシンプルなインターフェースを提供している ElementTree モジュールを使用する のがよいでしょう。
Document オブジェクトを取得する
minidom を使用して、XML の各要素にアクセスするためには、まずは DOM 全体を表現する xml.dom.minidom.Document
オブジェクトを取得する必要があります。
データソースとしては、XML ファイル、XML 文字列、Web 上のリソースなどを利用できます。
XML ファイルを扱う場合
from xml.dom import minidom
doc = minidom.parse("input.xml")
print(doc.toxml())
XML 文字列を扱う場合
from xml.dom import minidom
xml = """
<tree>
<branch>
<leaf id='1'>Leaf 1</leaf>
<leaf id='2'>Leaf 2</leaf>
<leaf id='3'>Leaf 3</leaf>
</branch>
</tree>"""
doc = minidom.parseString(xml)
print(doc.toxml())
Web 上の XML リソースを扱う場合
urllib
モジュールを組み合わせて使えば、Web 上の XML も簡単にパースできます。
from urllib.request import urlopen
from xml.dom import minidom
with urlopen("https://example.com/test.xml") as res:
doc = minidom.parse(res)
print(doc.toxml())
DOM リソースの解放
使用し終わった Document
オブジェクトは、ガーベジ・コレクションによって自動的に解放されますが、unlink
メソッドで明示的に解放することもできます。
dom.unlink()
Document
オブジェクトを生成するときに with
構文を使用すれば、unlink
処理を自動化することができます。
with minidom.parse("input.xml") as doc:
print(doc.toxml())
タグ名を指定して要素を取得する (getElementsByTagName)
Document#getElementsByTagName
メソッドを使うと、指定したタグ名の要素のリスト(NodeList
オブジェクト)を取得することができます。
子ノードを再帰的に検索するので、同じタグ名を持つ要素はすべてリストに含まれます。
ノードが見つからない場合は、None
が返されます。
books = doc.getElementsByTagName("book")
上記の例では、Document
オブジェクトの getElementsByTagName
メソッドを呼び出しているので、全てのノードが検索対象になりますが、特定のノード (Element
) の getElementsByTagName
メソッドを呼び出すと、そのノード以下のノードのみが検索対象となります。
authors = books[0].getElementsByTagName("author")
テキストノードの値を取得する
属性値を取得する
ノードの子ノードを全て取得する
childNodes = node.childNodes
ノード名(要素名)を取得する
指定した要素をループで処理する
次の例では、book
というタグ名の要素をすべて取得してループ処理しています。
子ノードをループで処理する
次の例では、books
以下の複数の子ノード (book
) をループ処理しています。
ノードがテキストノードが調べる
if node.nodeType == node.TEXT_NODE:
print "This is a text node"
ノードに属性を追加する/属性の値を変更する
Element
オブジェクトの setAttribute(self, attname, value)
メソッドを使用して、任意のノードの属性を設定することができます。
テキストノードの値を変更する
Element
オブジェクトの nodeValue
属性の値を設定することで、テキストノードの値を変更することができます。