078:XMLを解析する
以下の XML を解析対象としてみます。この XML は builtin.xml というファイルに収まっているものとします。
<?xml version="1.0" encoding="utf-8" ?>
<built-in>
<type>
<name>int</name>
<class>numeric</class>
</type>
<type>
<name>float</name>
<class>numeric</class>
</type>
<type>
<name>str</name>
<class>sequence</class>
</type>
<type>
<name>list</name>
<class>sequence</class>
</type>
<type>
<name>tuple</name>
<class>sequence</class>
</type>
<type>
<name>dict</name>
<class>mapping</class>
</type>
</built-in>
これから紹介するコードは各モジュールを用いて builtin.xml から次の出力を得るものです。
int float str list tuple dict
ElementTree?
Python で XML を読む方法は多数あるのですが、まずは ElementTree? を紹介します。 Python 2.5 より標準入りした使いやすいモジュールです。 XML を Python オブジェクトのツリーとし、直感的に扱えるようにしてくれます。
import xml.etree.ElementTree as ET
tree = ET.parse('builtin.xml')
for element in tree.getroot():
print element.find('name').text
SAX
Python には SAX の実装 sax が用意されています。SAX はイベント駆動型の標準 API です。
import sys
import xml.sax
from xml.sax.handler import ContentHandler
class printNameHandler(ContentHandler):
def __init__(self, writer=sys.stdout):
self._writer = writer
self._node = []
ContentHandler.__init__(self)
def startElement(self, name, attrs):
self._node.append(name)
def endElement(self, name):
self._node.pop()
_name_node = [u'built-in', u'type', u'name']
def characters(self, data):
if self._node == self._name_node:
self._writer.write(u'%s\n' % data)
parser = xml.sax.make_parser()
parser.setContentHandler(printNameHandler())
parser.parse(u'builtin.xml')
DOM
Python には DOM の簡易実装 minidom が用意されています。DOM は W3C 勧告の標準 API で、文章データをツリー構造として扱います。 minidom とは DOM 1.0 にいくつかの DOM 2 の機能を追加したものです。
import xml.dom.minidom
dom = xml.dom.minidom.parse(u'builtin.xml')
for name in dom.getElementsByTagName(u'name'):
print name.firstChild.data
Expat
Python には C言語で書かれたストリーム志向パーサー Expat およびそのラッパーが用意されています。
import xml.parsers.expat
_node = []
_name_node = [u'built-in', u'type', u'name']
def start_element(name, attrs):
_node.append(name)
def end_element(name):
_node.pop()
def character_data(data):
if _node == _name_node:
print data
parser = xml.parsers.expat.ParserCreate()
parser.StartElementHandler = start_element
parser.EndElementHandler = end_element
parser.CharacterDataHandler = character_data
xml = open(u'builtin.xml')
try:
parser.ParseFile(xml)
finally:
xml.close()
BeautifulSoup?
サードパーティ製モジュールにも便利なものがあります。そのうちの1つ、 BeautifulSoup? を紹介します。 BeautifulSoup? は ElementTree? のように XML を Python で扱いやすいオブジェクトのツリーに変換してくれます。
from BeautifulSoup import BeautifulStoneSoup
soup = BeautifulStoneSoup(open(u'builtin.xml', 'rb').read())
for name in soup.findAll('name'):
print name.string
より高度、実験的なモジュールたち
ここまでは XML を手軽に扱う方向で作成されたモジュールでしたが、より高度な機能を必要とする場合もあるかと思います。次のものが役に立つでしょう。
- PyXML?
- XML-SIG の PyXML? は DOM の完全な実装を提供しています。
- 4Suite
- 4Suite はXPATH, XSLT, XLink?, XPointer?, RDF のような XML 関連の実装を提供しています。