覚書: xml.saxとelementtree.SimpleXMLWriterを使ったXMLフィルター
読み込んだXMLと同等のものを出力するフィルター。SAXなんで巨大なXMLファイルでも処理できる。
import sys
import xml.sax.handler
from elementtree.SimpleXMLWriter import XMLWriter
import codecsclass Parser(xml.sax.handler.ContentHandler):
""" 読み込んだXMLと同等のもを掃き出す何もしないフィルター """def __init__(self, outfh=sys.stdout):
self.w=XMLWriter(outfh, encoding='utf8')
# ウインドーズで読み込むにはボムじいさんをつけておくといいらしい。
outfh.write(codecs.BOM_UTF8)# elementtree.SimpleXMLWriter.declaration()はエンコーディングを
#「utf8」とするんだけど、これだとxml.saxが嫌がる。誰が正しいのかわからないが
#「utf-8」にするためにxml宣言をハードコードしておく。
#self.w.declaration()
sys.stdout.write('')def startElement(self, name, attrs):
self.w.start(name, **attrs)
def endElement(self, name):
self.w.end()
def characters(self, content):
self.w.data(content)
def done(self):
pass
if __name__=='__main__':
import baker
@baker.command
def filter(xml_file):
parser=Parser()
xml.sax.parse(file(xml_file), parser)baker.run()
XMLってそもそも木構造のドキュメントを表記するためのものでしょ。データstreamの処理には向かないと思う。そういうときにはsaxでもっと扱いやすい表記法に変換する。 処理したデータをXMLにして返さなきゃいけないときはelementtree.SimpleXMLWriterが便利。