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

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

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

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

Python 3.x

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

Q&A

解決済

1回答

1436閲覧

XMLからの属性の抽出

tecton00

総合スコア8

XML

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

Python 3.x

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

0グッド

0クリップ

投稿2017/08/26 07:53

###前提・実現したいこと
以下のようなXMLから指定した属性値と対応するテキストを抽出することを考えています。<doc></doc>で挟まれたノードに含まれる属性は一定ではなく、欠損している場合もあります。
添付のコードは抽出したい属性値をリスト形式で与え、それに合致したものを抽出するという考え方で書いており、期待している出力は以下の通りです。

[{'Key': 'key-A', 'Body': 'body-A', 'ID': 'A'},
{'Key': 'key-B', 'Body': 'body-B', 'Header': 'head-B', 'ID': 'B'},
{'Key': 'key-C', 'Body': 'body-C', 'ID': 'C'},
{'Key': 'key-D', 'Body': 'body-D', 'Header': 'head-D', 'ID': 'D'}]

XML

1<database> 2<doc id="A"> 3<item name="Key">key-A</item> 4<item name="Body">body-A</item> 5</doc> 6<doc id="B"> 7<item name="Key">key-B</item> 8<item name="Body">body-B</item> 9<item name="Header">head-B</item> 10</doc> 11<doc id="C"> 12<item name="Body">body-C</item> 13<item name="Key">key-C</item> 14</doc> 15<doc id="D"> 16<item name="Body">body-D</item> 17<item name="Key">key-D</item> 18<item name="Header">head-D</item> 19</doc> 20</database>

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

実際の出力は以下の通りで、Headerの属性値が存在しない"C"のノードに"B"のHeaderの値が入力されてしまいます。 [{'Key': 'key-A', 'Body': 'body-A', 'ID': 'A'}, {'Key': 'key-B', 'Body': 'body-B', 'Header': 'head-B', 'ID': 'B'}, {'Key': 'key-C', 'Body': 'body-C', 'Header': 'head-B', 'ID': 'C'}, {'Key': 'key-D', 'Body': 'body-D', 'Header': 'head-D', 'ID': 'D'}] for in や変数の使い方に問題があるのかと思いますが、解決方法がわかりません。 アドバイスよろしくお願いいたします。

###該当のソースコード

Python

1from xml.etree.ElementTree import * 2 3tree = parse("XML.xml") 4root = tree.getroot() 5iList=["Key", "Body", "Header","Other"] 6xList=[] 7xDict={} 8 9for doc in root.findall('doc'): 10 ID = doc.attrib["id"] 11 for item in doc.findall('item'): 12 for List in iList: 13 if item.attrib["name"] == List: 14 text = str(item.text) 15 else: 16 continue 17 xDict[List] = str(text) 18 xDictCopy = xDict.copy() 19 xDictCopy["ID"] = ID 20 xList.append(xDictCopy) 21print(xList)

###試したこと
対応する属性が存在しない場合は空を出力するようにコード16行目の“Continue”の部分を
text = ""
とすると、今度は対応するテキストがあるはずの部分も空になってしまいます。

[{'Key': '', 'Body': 'body-A', 'Header': '', 'Other': '', 'ID': 'A'},
{'Key': '', 'Body': '', 'Header': 'head-B', 'Other': '', 'ID': 'B'},
{'Key': 'key-C', 'Body': '', 'Header': '', 'Other': '', 'ID': 'C'},
{'Key': '', 'Body': '', 'Header': 'head-D', 'Other': '', 'ID': 'D'}]
###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報

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

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

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

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

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

guest

回答1

0

ベストアンサー

xDictがループ内で初期化されていないため、以前の情報が残ってしまっています。
Listの内容を取得する前にxDictの内容を再度空とすることで対応が可能かと思います。

(略) for doc in root.findall('doc'): ID = doc.attrib["id"] for item in doc.findall('item'): xDict = {} for List in iList: (略)

投稿2017/08/26 09:27

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

tecton00

2017/08/26 09:44

早速のご回答ありがとうございます! 最初のfor文の後に"xDict = {}"を入れることで思った通りの出力ができました。 おかげさまで1週間悩んでいたことが解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問