Flask x XML

久々にプログラマっぽいエントリでも。
Flask で XML 出力の話。


正直な所、PythonXML 出力は面倒臭いです。
JSON で良いじゃん! JSON で! ってなります。


しかし XML 出力しなきゃいけない時もあるわけで。


これひょっとしたら HTML と同様に Jinja2 使えば出来るんじゃね?
と思いついたのでやってみました。



ファイル構成は必要最低限で。

  • xml_tips
    • main.py
    • templates


まず main.py 。割と適当。

# -*- coding: utf-8 -*-
from flask import Flask, Response, make_response, render_template
app = Flask(__name__)


@app.route("/")
def index():
    """
    Index
    """
    body = ""
    body += '<a href="xml/show/">xml show</a><br />'
    body += '<a href="xml/dl/">xml download</a><br />'
    return Response(body)


@app.route("/xml/show/")
def xml_show():
    """
    XML データ表示
    """
    data_list = _make_data_list()
    return Response(
        render_template("data.xml", data_list=data_list),
        mimetype="application/xml"
    )


@app.route("/xml/dl/")
def xml_download():
    """
    XML ファイル ダウンロード
    """
    data_list = _make_data_list()
    response = make_response()
    response.data = render_template("data.xml", data_list=data_list)
    response.headers['Content-Type'] = 'application/xml'
    response.headers['Content-Disposition'] = 'attachment;filename=data.xml'
    return response


def _make_data_list():
    """
    データ作成
    """
    result = []
    result.append(dict(id=1, name="P"))
    result.append(dict(id=2, name="Y"))
    result.append(dict(id=3, name="T"))
    result.append(dict(id=4, name="H"))
    result.append(dict(id=5, name="O"))
    result.append(dict(id=6, name="N"))
    return result


if __name__ == '__main__':
    app.run(debug=True)


続いて data.xml。何かもう最低限。
HTML と同様に for 回したり、変数埋め込んだり。

<?xml version="1.0" encoding="utf-8"?>
<data>
    {% for data in data_list %}
        <plot id="{{ data.id }}">{{ data.name }}</plot>
    {% endfor %}
</data>

これを起動すると、

$ python main.py
 * Running on http://127.0.0.1:5000/
 * Restarting with reloader


xml show」と「xml download」のリンクが表示されます。
xml show」を押下すると、XML を表示します。
xml download」を押下すると、XML のダウンロードが出来ます。


試してみて驚いたのは、
Reponse に data として render_template を渡しても問題ない事ですなー。


もっと複雑な事しなきゃいけない場合は使えないかもしれませんが、
簡易的な場合はこれで行けるかと。
ご参考までに。