0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

外部実体がリモートにあるXML文書をPythonのlxmlで解析する

Posted at

Pythonのライブラリーであるlxmlは(lxmlも1)、デフォルトでは外部実体(外部エンティティ、external entity)を読みに行きません。

解決方法が公式に書いてあって2、XML Catalogsによる方法も紹介されてるのですが、URI Resolversを書く方法を使ってみました。この方法で、取得した外部実体をファイルとして保存しておけば、問題があって調べるときなどいろいろ便利かな…ということで。

以下は、JATS XMLをバリデートしてみたとき1のスクリプトです。

lxmlに対して外部実体を解決しながら、あわせて次を行います: entityというフォルダが既にある前提で

  • 取ってきた外部実体をentityフォルダの下に保存しておきます
  • 標準出力(print())に外部ファイルのURL、公開識別子、保存したファイル名(URLのbasename)をカンマ区切りで出力します
from lxml import etree
import argparse
import os
import sys
import requests

arg_parser = argparse.ArgumentParser()
arg_parser.add_argument("file", help="XML file to validate.")
args = arg_parser.parse_args()
print(f'start parsing {args.file}')

count = 0
entity_folder = 'entity'

print("url,id,basename")
class DTDResolver(etree.Resolver):
    def resolve(self, url, id, context):
        if url.startswith('http'):
            global count
            count += 1
            res = requests.get(url)
            # 読み込んだリモートのファイルを保存しておく
            file_name = os.path.basename(url)
            with open(f"{entity_folder}/{file_name}", mode='w') as f:
                f.write(res.text)
            print("'%s','%s,'%s'" % (url, id, file_name))
            return self.resolve_string(res.text, context)
        else:
            f = open(url, 'r')
            return self.resolve_file(f, context)

parser = etree.XMLParser(dtd_validation=True, no_network=False)
parser.resolvers.add( DTDResolver() )

try:
    tree = etree.parse(args.file, parser=parser)
except etree.XMLSyntaxError as e:
    print(f'etree.XMLSyntaxError: {e}')
finally:
    print(f'Loaded {count} remote entities and stored under the "{entity_folder}" folder.')

  1. 外部実体の解決 - 無料のVisual Studio CodeとXML拡張機能でJATS XMLを編集する https://qiita.com/yamahige/items/c25f10f2177cc4d9df90#%E5%A4%96%E9%83%A8%E5%AE%9F%E4%BD%93%E3%81%AE%E8%A7%A3%E6%B1%BA 2

  2. Document loading and URL resolving - lxml https://lxml.de/resolvers.html

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?