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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

443閲覧

xmlから取得した文章をpythonを使用して、Wordファイル上で問題文形式にする。

harruya

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/02/05 03:49

編集2023/02/06 11:25

実現したいこと

xmlから取得した文章をWordファイル上で問題文形式にする。

ここに質問の内容を詳しく書いてください。
現在xmlから取得した文章をPythonを利用して、wordファイル上で問題文形式にしようとしています。問題用紙作成ツールを作成しています。
Pyton-docxのライブラリである、replace文を用いて、文章を変更ができますが、それを一つ一つの文章に直したら、きりがありません。
更に、他の問題形式では、また修正する必要があります。
xml.etree.ElementTreeとPython-docxを利用して、wordファイル上に書き込むことができました。一番上の図を真ん中の図のような形に直したいです。
イメージ説明

イメージ説明

イメージ説明

該当のソースコード

Pythonの文章
import defusedxml.ElementTree as ET
import docx
docw = docx.Document()
tree = ET.parse('res00001.dat')

for mat_formattedtext in tree.iter('mat_formattedtext'):
if mat_formattedtext.text==None:
pass
else:

print(mat_formattedtext.text) docw.add_paragraph(mat_formattedtext.text)

for i in range(19):
para2=docw.paragraphs[i]
t = para2.text
t = t.replace("<p>", " ")
t = t.replace("</p>", " ")
t = t.replace("<br>", " ")
para2.text = t
docw.save('pp3-word.docx')

xml形式
<mat_extension>
<mat_formattedtext type="HTML"><p>以下の選択肢の中から県庁所在地である都市を選べ</p></mat_formattedtext>
</mat_extension>
</material>
</flow>
</flow>
<flow class="RESPONSE_BLOCK">
<response_lid ident="response" rcardinality="Single" rtiming="No">
<render_choice shuffle="No" minnumber="0" maxnumber="0">
<flow_label class="Block">
<response_label ident="c34670ec81e44256b8afafe49d3558a7" shuffle="Yes" rarea="Ellipse" rrange="Exact">
<flow_mat class="FORMATTED_TEXT_BLOCK">
<material>
<mat_extension>
<mat_formattedtext type="HTML"><p>下野市</p></mat_formattedtext>
</mat_extension>
</material>
</flow_mat>
</response_label>
</flow_label>
<flow_label class="Block">
<response_label ident="becb10b95e664ade9733ff12fb8773de" shuffle="Yes" rarea="Ellipse" rrange="Exact">
<flow_mat class="FORMATTED_TEXT_BLOCK">
<material>
<mat_extension>
<mat_formattedtext type="HTML"><p>宇都宮市</p></mat_formattedtext>
</mat_extension>
</material>
</flow_mat>
</response_label>
</flow_label>
<flow_label class="Block">
<response_label ident="6fed8b45824e4b69885523523c1e9caa" shuffle="Yes" rarea="Ellipse" rrange="Exact">
<flow_mat class="FORMATTED_TEXT_BLOCK">
<material>
<mat_extension>
<mat_formattedtext type="HTML"><p>日光市</p></mat_formattedtext>
</mat_extension>
</material>
</flow_mat>
</response_label>

試したこと

replace文で文章を変更する。
以下の選択肢➛ 質問1 以下の選択肢
下野市➛A.下野市
ソースコード
import defusedxml.ElementTree as ET
import docx
docw = docx.Document()
tree = ET.parse('res00001.dat')

for mat_formattedtext in tree.iter('mat_formattedtext'):
if mat_formattedtext.text==None:
pass
else:

print(mat_formattedtext.text) docw.add_paragraph(mat_formattedtext.text)

for i in range(19):
para2=docw.paragraphs[i]
t = para2.text
t = t.replace("<p>", " ")
t = t.replace("</p>", " ")
t = t.replace("<br>", " ")
para2.text = t
docw.save('pp3-word.docx')
para3=docw.paragraphs[1]
s = para3.text
s = s.replace("以下の選択肢の中", "質問1 以下の選択肢 ")
para3.text = s
docw.save('pp3-word.docx')
para4=docw.paragraphs[2]
d = para4.text
d = d.replace("下野市", "A.下野市 ")
para4.text = d
docw.save('pp3-word.docx')

イメージ説明

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

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

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

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

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

guest

回答1

0

こちらの質問ですが、わかりにくいところや意図がつかめない部分が3箇所あります。
・XMLの全体的な構造(pタグのどれが抽出対象で処理対象?)
・選択問題が、A,B,C,Dではなく、A,B,C,E?
・処理の順序が、XML→Word→編集?

上記の部分を想像で補いながらですが、自分ならこうするというもので回答します。

  1. 自分ならXML→編集→Wordの順序に処理します。
  2. 問題文の末尾が"選べ”であれば選択問題と判断
  3. 選択肢のテキストにはA, B, C, Dなどを付与する際には、選択肢の数を数える変数を設定し、剰余の式を使います。

たとえば、下記のようなコードにすると思います。

Python

1import defusedxml.ElementTree as ET 2import docx 3docx = docx.Document() 4tree = ET.parse('./test.xml') 5count = 0 6for text in tree.iter('p'): 7 if count == 0 and text.text[-2:] == "選べ": 8 count += 1 9 print(text.text) 10 else: 11 if count != 0: 12 if count % 4 == 1: 13 print("A.", text.text) 14 15 if count % 4 == 2: 16 print("B.", text.text) 17 18 if count % 4 == 3: 19 print("C.", text.text) 20 21 if count % 4 == 0: 22 print("D.", text.text) 23 count = 0 24 continue 25 26 count += 1 27 else: 28 print(text.text)

上記コードであれば、printとしているところをdocx.add_paragraph("A." + child.text)などに変え、最後にdocx.save()を付け加えればよいのではと思います。

こちらあくまでもXMLの全体構造が不明(たとえば、選択肢は常に4択なのか?)な部分を想像で補ったものですのでご注意ください。

投稿2023/02/06 02:25

TKMoon

総合スコア79

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問