質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

ダウンロード

リモートシステムからローカルシステムへとデータを受信する事、もしくはそのようなデータ転送を行う事をダウンロードと呼びます。

Q&A

1回答

1800閲覧

Flaskでxmlをダウンロードさせたいが、前回処理したファイルが残ってしまう

hamident0

総合スコア6

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

ダウンロード

リモートシステムからローカルシステムへとデータを受信する事、もしくはそのようなデータ転送を行う事をダウンロードと呼びます。

0グッド

0クリップ

投稿2020/09/15 14:18

前提・実現したいこと

Flaskで、「xml形式のファイル(拡張子は.eaf)をアップロードし、それを書き換えてダウンロードさせる」というアプリケーションを作ろうとしています。

発生している問題・エラーメッセージ

アプリケーションを立ち上げた直後1回目の処理はうまくいき、ファイルもダウンロードできます。しかし、その後の処理では、初回と全く同じ中身のファイルがダウンロードされてしまいます。
Pythonのソースコードの「#ファイルを保存」以降の部分が良くないと思うのですが、どうすればよいのかわかりません。
どのようにすれば、その回に処理したファイルをダウンロードできるでしょうか?

該当のソースコード

Python3

1# -*- coding: utf-8 -*- 2#Flaskとrender_template(HTMLを表示させるための関数)をインポート 3from flask import Flask,render_template,request,Markup,Response,make_response 4from werkzeug.utils import secure_filename 5import re,os 6import xml.etree.ElementTree as ET 7 8app = Flask(__name__) 9 10@app.route("/", methods=["get","post"]) # ルートにアクセスされたときの処理 11def entry(): 12 return render_template("index.html") 13 14@app.route('/upload', methods=['POST']) 15def upload(): 16 # テキストファイルの取得 17 txt_file = request.form['input_text'] 18 text = txt_file.splitlines() 19 text_list = [] 20 translation_list = [] 21 22 # 奇数行目をtextとして、偶数行目をtranslationとしてリストに加える 23 i = 1 24 for line in text: 25 if i % 2 == 1: 26 line = re.sub(r"([^ ])(-|=)",r"\1 \2",line) 27 line = re.sub(r"(,|.)","",line) 28 line = re.sub(r"^*","* ",line) 29 text_list.append(line) 30 elif i % 2 == 0: 31 translation_list.append(line) 32 i += 1 33 34 # eafファイルをリクエストし、パーシングしてルートを取る 35 tree = ET.parse(request.files["eaf_file"]) 36 # tree = ET.parse("app/static/14_受動表現.eaf") 37 root = tree.getroot() 38 39 # 指定された名前のtierの中身を取得 40 for child in root: 41 if child.tag == "TIER" and child.attrib["TIER_ID"] == request.form["tier_name_text"]: 42 content_tier_text = child 43 if child.tag == "TIER" and child.attrib["TIER_ID"] == request.form["tier_name_translation"]: 44 content_tier_translation = child 45 46 # テキストと訳の文章をeafに書き込む 47 i = 0 48 for child in content_tier_text: 49 child[0][0].text = text_list[i] 50 i += 1 51 if i == len(text_list): 52 break 53 54 i = 0 55 for child in content_tier_translation: 56 child[0][0].text = translation_list[i] 57 i += 1 58 if i == len(text_list): 59 break 60 61 #ファイルを保存 62 tree.write("app/templates/new.eaf","utf-8") 63 response = make_response() 64 response.data = render_template("new.eaf") 65 response.headers['Content-Type'] = 'application/xml' 66 response.headers['Content-Disposition'] = 'attachment;filename=new.eaf' 67 return response 68 69if __name__ == "__main__": 70 app.run(debug=True) 71

該当のソースコード

html

1<!DOCTYPE html> 2<html> 3 <head></head> 4 <body> 5 <form method="post" action="/upload" enctype="multipart/form-data"> 6 空の注釈を作ったeafファイルを選択する<br> 7 <input type="file" name="eaf_file"><br><br> 8 文が入った注釈層の名前を入力 9 <input type="text" name="tier_name_text" value="text"><br> 10 訳文が入った注釈層の名前を入力 11 <input type="text" name="tier_name_translation" value="tl"><br><br> 12 例文を奇数行目に、訳を偶数行目に入力してください。<br> 13 <textarea type="text" name="input_text" rows= "10" cols="40"></textarea> 14 <input type="submit" value="分析する"> 15 </form> 16 </body> 17</html> 18

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ぱっと見た感じ、render_template()を誤解しているのが原因に見えます。
render_templateはjinja2テンプレートをレンダリングに使うもので、ダウンロード対象を読み込むために使うものではないので、ioをresponse.data()に渡してあげれば動くと思います。
サーバ側でファイルに落として(落とす先としてtemplatesを使うのはやめた方が良いと思いますが)、それをダウンロードするだけならsend_file()も使う事ができます。
ファイルを保存し、ダウンロードさせる場合、ダウンロードさせたあとに残ったファイルをどうするかを検討する必要があるのに気をつけてください。

以下、ダウンロードできる事を確認したソースです。

flask --version Python 3.7.4 Flask 1.1.2 Werkzeug 1.0.1

python

1from io import SEEK_SET, SEEK_END, BytesIO 2import xml.etree.ElementTree as ET 3 4from flask import Flask, request, render_template, make_response, send_file 5 6app = Flask(__name__) 7 8app.config['MAX_CONTENT_LENGTH'] = 1 * 1024 * 1024 9 10 11@app.route('/upload', methods=['GET', 'POST']) 12def upload(): 13 if request.method == 'GET': 14 return render_template('upload.html') 15 elif request.method == 'POST': 16 file = request.files['eaf_file'] 17 file.seek(0, SEEK_END) 18 file.write('\r\nadded text'.encode('utf-8')) 19 file.seek(0, SEEK_SET) 20 response = make_response() 21 response.data = file.read() 22 response.headers['Content-Disposition'] = 'attachment; filename=eaf_file.eaf' 23 response.mimetype = 'text/xml' 24 return response 25 26 27@app.route('/upload2', methods=['GET', 'POST']) 28def upload2(): 29 if request.method == 'GET': 30 return render_template('upload2.html') 31 elif request.method == 'POST': 32 file = ET.parse(request.files['eaf_file']) 33 root = file.getroot() 34 for child in root.iter('day'): 35 child.set('attr', 'attribute') 36 f = BytesIO() 37 file.write(f, encoding='utf-8', xml_declaration=True) 38 f.seek(0, SEEK_SET) 39 response = make_response() 40 response.data = f.read() 41 response.headers['Content-Disposition'] = 'attachment; filename=eaf_file.eaf' 42 response.mimetype = 'text/xml' 43 return response

html

1<!-- upload.html --> 2<!DOCTYPE html> 3<html lang="ja"> 4<head> 5 <meta charset="UTF-8"> 6 <title>upload</title> 7</head> 8<body> 9 <form method="post" action="{{ url_for('upload') }}" enctype="multipart/form-data"> 10 <input type="file" name="eaf_file"> 11 <input type="submit" value="分析する"> 12 </form> 13</body> 14</html>

html

1<!-- upload2.html --> 2<!DOCTYPE html> 3<html lang="ja"> 4<head> 5 <meta charset="UTF-8"> 6 <title>upload</title> 7</head> 8<body> 9 <form method="post" action="{{ url_for('upload2') }}" enctype="multipart/form-data"> 10 <input type="file" name="eaf_file"> 11 <input type="submit" value="分析する"> 12 </form> 13</body> 14</html>

eaf_file.eaf

xml

1<?xml version="1.0" encoding="UTF-8"?> 2<diary> 3 <day date="2006-08-30" title="ようやくXML Schemaの勉強開始" > 4 <body>今日XML Schemaの勉強を開始しました。結構難しい・・・</body> 5 </day> 6 <day date="2006-08-31" title="はやくもXML Schema完全制覇!" > 7 <body>なんとXML Schemaを自力で作成できるようになりました。</body> 8 </day> 9</diary>

投稿2020/09/16 05:51

FiroProchainezo

総合スコア2401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hamident0

2020/09/16 10:49

ご回答ありがとうございます。ご指摘の通り、render_template()を、単純に出力を出すものと勘違いしておりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問