今回は「社会保険の算定基礎届の電子通知書」にも利用されている電子公文書のXMLとXSLをPythonでHTML形式に変換する方法を説明します。
最近は社会保険の算定基礎届を電子申請にしている企業も多いと思いますが、申請時に「紙の通知書を希望する」にチェックしていないと電子通知書だけが発行されます。電子通知書は8月ごろになると「電子公文書」としてe-Gov電子申請 のアプリケーションを利用して自分でダウンロードできます。
弊社も遅ればせながら今年から電子申請してみましたが、ダウンロードした通知書のZIPファイルを展開してみると、PDFがあるかと思ったら、予想外の「XML + XSL」でした。
Internet Explorer ならすぐに表示できますが、サポートは今年の6月に終了 しています。今後はXMLのままだと内容が確認しづらいので、何らかの方法が必要になります。
そこで、弊社ではXMLとXSLを1つにまとめたHTMLファイルを作成しておくようにしました。そうすればブラウザで開くだけで、紙の通知書と同じ様式で内容を確認できます。
HTMLファイルへの変換はPythonを利用すると簡単にできます。今回はその方法をご紹介します。
本記事の目次
Internet Explorer以外のブラウザでXMLファイル形式の公文書を開くには
今回のXMLとXSLは、EdgeとSafariでも表示することはできますが、以下のe-Govポータルのお知らせで説明されているような設定が必要になります。
Internet Explorerサポート終了後の電子公文書ファイルの参照方法について
IEサポート終了に伴うe-Govへの影響について
準備:lxmlライブラリのインストール
XML + XSL → HTML の変換を行うには、いわゆる「XMLパーサー」と呼ばれるツールを使います。XMLパーサーは標準ライブラリにもありますが、今回はlxml という外部ライブラリを利用します。lxmlはXMLやHTMLの処理を柔軟にしてくれるので、Webスクレイピングでも人気です。
lxmlはpip
でインストールできます。自分の環境に応じて適切なコマンドでインストールしておきます。一般には以下のようなコマンドが用いられます。pipの詳細について知りたい場合はこちらの記事が参考になります。
[Windows]
> py -m pip install lxml
[Mac]
> python3 -m pip install lxml
XSLとは
XMLはタグ付けされたテキストファイルですが、そのデータを目的に応じて見せ方を変えられるようにしてくれるのが「XSL(Extensible Stylesheet Language)」です。おおざっぱに言えば両者はHTMLとCSSの関係に似ています。XSLは、XMLを変換するための「XSLT(XSL Transformations)」と組み版の指定を行う「XSL-FO(XSL Formatting Object)」で構成されます。
プログラムの作成
e-Gov電子申請からダウンロードした電子通知書は、20220701100223A750.zip
のような到達番号をファイル名にしたZIP形式のファイルになっています。展開するとXML形式(*.xml)とXSL形式(*.xsl)のファイルがあるのを確認できます。
そのなかの7130001.xml
が「健康保険・厚生年金保険被保険者標準報酬決定通知書」のデータ、7130001.xsl
がそのスタイルシートになります。これらのファイル名は固定されています 。
以下のプログラムで上記の2つのファイルを1つのHTMLファイルにまとめることができます。
xml2html.py
from lxml import etree
xml_tree = etree.parse("7130001.xml")
xsl_tree = etree.parse("7130001.xsl")
transform = etree.XSLT(xsl_tree)
html = transform(xml_tree)
html.write("7130001.html", pretty_print=True)
7130001.xml
と7130001.xsl
をカレントディレクトリに入れて、このプログラムを実行すると7130001.html
が作成されます。ブラウザで表示すると以下のように通知書の内容を確認できます。
以上のように10行に満たないコードで簡単にHTMLファイルに変換できました。
標準報酬決定通知書以外のデータがある場合(参考)
電子通知書に標準報酬決定通知書以外のデータがある場合は、その都度ファイル名を変更するのは面倒です。例えば、「70歳以上被用者算定基礎届」は7200001.xml
と7200001.xsl
になります。
そこで、ZIPファイルの中にあるXMLとXSLのペアを自動的に検索してHTMLに変換するプログラムを参考までに掲載しておきます。
zip2html.py
import os
import zipfile
from lxml import etree
# 電子通知書のZIPファイル
zip_file = zipfile.ZipFile("20220701100223A750.zip")
# ZIPファイル内のXMLとXSLのリスト
xml_paths = [name for name in zip_file.namelist() if name.endswith(".xml")]
xsl_paths = [name for name in zip_file.namelist() if name.endswith(".xsl")]
# XMLファイルごとにループ
for xml_path in xml_paths:
directory, xml_file_name = os.path.split(xml_path)
# ZIPからXMLファイル読み込み
xml = zip_file.read(xml_path)
xml_tree = etree.fromstring(xml)
# XMLからペアになるXSLファイル名を読み取る(XPATH使用)
elem = xml_tree.xpath("/processing-instruction('xml-stylesheet')")[0]
xsl_file_name = elem.get("href")
# ペアになるXSLのパス
xsl_path = os.path.join(directory, xsl_file_name)
if xsl_path in xsl_paths:
# ZIPからXSLファイル読み込み
xsl = zip_file.read(xsl_path)
xsl_tree = etree.fromstring(xsl)
# XML + XSL => HTML
transform = etree.XSLT(xsl_tree)
html = transform(xml_tree)
# HTMLファイル書き込み
os.makedirs("html", exist_ok=True) # html用のフォルダをつくる
html_path = os.path.join("html", xml_file_name.split(".")[0] + ".html")
html.write(html_path, pretty_print=True)
ここで、XMLとペアになるXSLは以下のようなXMLファイルの「xml-stylesheet宣言」の属性href
の値から読み取ります。そのために、XPATHという構文を用いて宣言のタグを検索しています。
7130001.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="7130001.xsl"?>
...
本プログラムを実行すれば、ZIPファイルの中にあるすべてのXMLとXSLのペアがHTMLに変換されhtmlフォルダに保存されます。
今回は、ZIPファイル名をコードに直接書き込んでいますが、コマンドライン引数 を使えるようにすると毎回コードを書き換えなくても済むようになります。適宜使いやすいようにカスタマイズしてみてください。
最後に
電子申請自体は紙の書類の管理がなくなり、とても望ましいことなので、こちらもいろいろと工夫したいところです。そこにPythonも絡めると面白くなります。ぜひ参考にしてみてください。
なお、今回は電子通知書に同梱されているXSLファイルを用いましたが、以下で他の形式用のXSLファイルも公開されています。このXSLファイルを差し替えると「個別形式」ではなく「一覧表形式」で表示できるようになります。
電子申請を利用中の方へ(日本年金機構) > 4.電子通知書の形式変換
近年「働きやすい環境」の構築が重視されるにともない、総務やバックオフィスの仕事が注目されています。しかし、その仕事内容はあまりにも広範囲に及ぶので、以下のような書籍があると全体を把握しやすくなると思います。