🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
XML

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

Python 3.x

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

Python

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

Q&A

解決済

2回答

1698閲覧

Python 辞書の中のリスト

AbcdefgFirst

総合スコア33

XML

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

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2020/12/22 13:47

編集2020/12/28 05:29

イメージ説明いつもお世話になっております。
下記のようなxmlから辞書に変換したいのですが、自分の知識では正確な書き方が分かりませんでした。

補足事項

・欲しい辞書のキー⇒subcodesで固定

・欲しい辞書の値
{option name属性}:{option value属性}#{option name属性}:{option value属性}={SubCodeのcode属性} |
{option name属性}:{option value属性}#{option name属性}:{option value属性}={SubCodeのcode属性}

Subcode要素が増えたら区切り「|」の数が増えます。
Option要素が増えたら区切り「#」の数が増えます。
Option要素の数は変動しますが、各Subcode要素の中に入るOptionの数と並びは共通です。

分かり辛く申し訳ありません。。

xml

1 <Result> 2 <SubCodes> 3 <SubCode code="item-code-red-s"> 4 <Option name="カラー" value="red"/> 5 <Option name="サイズ" value="small"/> 6 </SubCode> 7 <SubCode code="item-code-red-m"> 8 <Option name="カラー" value="red"/> 9 <Option name="サイズ" value="medium"/> 10 </SubCode> 11     ・ 12     ・(中略) 13     ・ 14 </SubCodes> 15 </Result>

欲しい辞書型↓

python

1dict = {'subcodes:':'カラー:red#サイズ:small=item-code-red-s|カラー:red#サイズ:medium=item-code-red-m'}

試したコード

色々書いたり消したりして今のところ下記のコードになったのですが、これだと希望の区切り文字がバラバラのため区切り文字を変化させるのが難く躓いております。

python

1import xml.etree.ElementTree as ET 2 3subcodes = root.findall('Result/SubCodes/SubCode') 4dict = {} 5for subcode in subcodes: 6 lst = [] 7 code = subcode.attrib['code'] 8 options = subcode.findall('Option') 9 10 for option in options: 11 lst.append(option.attrib['name']) 12 lst.append(option.attrib['value']) 13 14 lst.append(code) 15 print(lst) 16 17 ''' 18 #一つの区切り文字しかできない 19 dict['subcodes'] = ','.join(lst) 20 21 #要素数が変動するので何番目などで条件分けできない 22 str = '' 23 for idx, val in lst: 24 if idx == 0: 25 str += val + ':' 26    (略) 27 ''' 28 29 30 31#lst 32#['カラー', 'red', 'サイズ', 'small', 'item-code-red-s'] 33#['カラー', 'red', 'サイズ', 'medium', 'item-code-red-m'] 34 35 36

エラー画面を添付しました。
このoptionの部分でInstance of dict has no attrib memberとなります。

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

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

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

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

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

meg_

2020/12/22 13:51

> 申し訳ありません。 > 質問入力ミスのためクローズ致します。 回答のある質問は削除できないのでは? 質問の削除は運営へ削除申請してください。
kai0310

2020/12/22 13:52

質問は修正できます。
guest

回答2

0

ベストアンサー

下記ではいかがでしょうか
※読み込むサンプルのXMLファイル(sample.xml)

xml

1 <Result> 2 <SubCodes> 3 <SubCode code="item-code-red-s"> 4 <Option name="カラー" value="red"/> 5 <Option name="サイズ" value="small"/> 6 </SubCode> 7 <SubCode code="item-code-red-m"> 8 <Option name="カラー" value="red"/> 9 <Option name="サイズ" value="medium"/> 10 </SubCode> 11 </SubCodes> 12 </Result>

 
コード(内包表記なし)

import xml.etree.ElementTree as ET with open("sample.xml", mode="r", encoding="utf-8") as f: xml_data = f.read() result = ET.fromstring(xml_data) subcodes = result[0] result_lst = [] for subcode in subcodes: subcode_lst=[] for option in subcode: option_lst=[] for attr in option.keys(): if attr in ["value", "name"]: option_lst.append(option.attrib[attr]) subcode_lst.append(':'.join(option_lst)) result_lst.append("#".join(subcode_lst)+"="+subcode.attrib["code"]) dic = {'subcodes':'|'.join(result_lst)} print(dic)

出力結果

>> {'subcodes:': 'カラー:red#サイズ:small=item-code-red-s|カラー:red#サイズ:medium=item-code-red-m'}

投稿2020/12/24 16:12

編集2020/12/28 05:47
sfdust

総合スコア1137

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

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

AbcdefgFirst

2020/12/24 17:50

sfdust様 ご回答ありがとうございます。 頂いたコードを試したところ希望通りの出力となりました(__) 説明のために省略しており申し訳ないのですが、SubCode要素の中にname属性またはvalue属性を持たない要素があった場合、keyerrorとなるのですがその場合どのように修正したら良いでしょうか? あまり自分が書き慣れないコードのため、修正の仕方が分からず度々すみません。 宜しくお願い致します。
sfdust

2020/12/24 23:58

対応するコードに直しました。
AbcdefgFirst

2020/12/28 01:28

度々ご回答ありがとうございます。 修正頂いたコードを試したところ、optionの部分で「Instance of dict has no attrib member」エラーとなります。
sfdust

2020/12/28 03:21

エラーが出たデータは質問と全く同じデータでしょうか?違うならば、そのデータをそのまま記載してください。
AbcdefgFirst

2020/12/28 04:45

データは同じなのですが、XMLのデータを読込む前に下記のdicに代入する部分をコードに記載したところ代入文のoptionがエラーと出ております。 dic = {'subcodes:': ('|'.join( '#'.join(':'.join(option.attrib[attr] for attr in option.keys() if attr in ["name", "value"]) for option in subcode) + "=" + subcode.attrib["code"] for subcode in subcodes))}
sfdust

2020/12/28 04:54 編集

すみません。「XMLのデータを読込む前に下記のdicに代入する部分をコードに記載した」のところが分かりません。 xmlデータをよみこんでおかないとそもそも分解できないと思うのですが・・・ 可能であれば、エラーが出たコードとxmlデータおよびそのエラー内容を全部そのまま記載していただけますか?(データについては、全部が無理でも同じエラーが出るのであれば省略したデータで構いません)
AbcdefgFirst

2020/12/28 05:34

ありがとうございます! 質問文を編集致しました。
sfdust

2020/12/28 05:46

自分がテストした場合のxmlデータを記載し、さらにコードを、内包表記を使わないものに修正しました。 これで試してみてください。
AbcdefgFirst

2020/12/28 05:57

度々ありがとうございます(__) 後程試させて頂きます!
guest

0

申し訳ありません。
質問入力ミスのためクローズ致します。

投稿2020/12/22 13:49

AbcdefgFirst

総合スコア33

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問