2013年3月19日火曜日

PythonのSAXで外部DTDを読みたくない

掲題の通り。

DTDにインターネットへの参照が

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
のようにあると、オフラインではファイルを取得できずにエラーとなってしまいます。DTDの中身を見たいわけでもないときには非常に残念です。

いまどきオフラインでの開発はほとんどありませんが、精神衛生上よろしくないので解決策を調べておくと、

from xml.sax import make_parser
from xml.sax.handler import feature_external_ges

parser = make_parser()
parser.setFeature(feature_external_ges, False)
f = open('some_file.xml')
parser.parse(f)
f.close()

feature_external_gesFalseにしてあげるだけでよいようです。

EntityResolverを用いて、あらかじめダウンロードしておいたDTDを参照することでもエラーを解消できます。

from xml.sax import make_parser
from xml.sax.handler import EntityResolver

class MyEntityResolver(EntityResolver):
    def resolveEntity(self, publicId, systemId):
        # ローカルに保存したDTDを開く
        return open(systemId.split('/')[-1], 'rb')

parser = make_parser()
parser.setEntityResolver(MyEntityResolver())

f = open('some_file.xml')
parser.parse(f)
f.close()

0 件のコメント:

コメントを投稿