2017-08-17 15 views
-3
ab= [['name Belgian Waffles', 'price $5.95', 'description Two of our famous Belgian Waffles ', 'calories 650'] ] 

私はノートのpythonのpython - CSVへの変換XML

Ex. : 
name    price  description       Calories 
Belgian Waffles $5.95  Two of our famous Belgian Waffles  650 

を使用して、表形式でCSVファイルにこのリストを解析したい:リストのサイズ異なる場合があります。値はさまざまです。ハードコーディングは必要ありません。

問題のXMLは、私は私がリスト

outerlist = [['name Belgian Waffles', 'price $5.95', 'description Two of our famous Belgian Waffles ', 'calories 650'] , ['name Berry-Berry Belgian Waffles','price $8.95','description Light Belgian waffles covered with an assortment ','calories 900']] 
として以下しまった次のPythonスクリプト

def innerHtml(root): 
    text = '' 
    nodes = [ root ] 
    while not nodes==[]: 
     node = nodes.pop() 
     if node.nodeType==xml.dom.Node.TEXT_NODE: 
      text += node.wholeText 
     else:    
      nodes.extend(node.childNodes)   
    return text 
innerlist=[] 
outerlist=[] 
string2=[] 

# To get tag value 
for statusNode in xmlFile.getElementsByTagName(xmlNode): 
    for childNode in statusNode.childNodes: 
     if childNode.nodeType==xml.dom.Node.ELEMENT_NODE: 
      if innerHtml(childNode).strip() != '': 
       string2.append(childNode.nodeName) 
       innerlist.append(childNode.nodeName+" 
       "+innerHtml(childNode).strip()) 
    outerlist.append(innerlist) 
    innerlist=[]  
    print (outerlist) 

を使用して、ルートなどの食品で最初のリストにそれを抽出しようとした

<?xml version="1.0" encoding="UTF-8"?> 
<breakfast_menu> 
    <food> 
    <name>Belgian Waffles</name> 
    <price>$5.95</price> 
    <description>Two of our famous Belgian Waffles with plenty of real maple 
    syrup</description> 
    <calories>650</calories> 
    </food> 
    <food> 
    <name>Berry-Berry Belgian Waffles</name> 
    <price>$8.95</price> 
    <description>Light Belgian waffles covered with an assortment of fresh 
     berries and whipped cream</description> 
    <calories>900</calories> 
    </food> 

です

私はCSV形式のPythonを使って書いてほしい。形式は

name   price  description  calories 
<name given> <price>  <description>  <calories> 
+2

のは、あなたの試みを見てみましょう。 – Miket25

答えて

1
ab= [['name Belgian Waffles', 'price $5.95', 'description Two of our famous Belgian Waffles ', 'calories 650']] 
(column_names, row_values) = (list() for i in range(2)) 

for newlist in range(0,len(ab)): 
    for i in range(0,len(ab[newlist])): 

     column = ab[newlist][i].split()[0] 

     if column not in column_names: 
      column_names.append(ab[newlist][i].split()[0]) 

     row_values.append(re.sub(column_names[i], '', ab[newlist][i]).strip()) 

df = pd.DataFrame(data=row_values).T 
df.columns = column_names 
file_name = "yourfilenameandpath" 
df.to_csv(file_name, sep='\t', encoding='utf-8') 

EDIT:

import pandas as pd 
from lxml import etree 

xmlfile = archive.open("xmlfile_name.xml") 
xmldoc = etree.parse(xmlfile) 
root = xmldoc.getroot() 

foods = root.find("breakfast_menu").findall("food") 

(name, price, description, calories) = (list() for i in range(4)) 

for food in foods: 
    name.append(food.find("name").text) 
    price.append(food.find("price").text) 
    description.append(food.find("description").text) 
    calories.append(food.find("calories").text) 

df= pd.DataFrame({"name": name, 
        "price": price, 
        "description": description, 
        "calories": calories) 
df.to_csv(file_name, sep='\t', encoding='utf-8') 
+0

ValueError:長さの不一致:予想される軸に20の要素があり、新しい値に4つの要素があります。次のエラーが返されます – Emmanuel

+0

あなたの編集に従った答えがより適切だと思います: 'lxml'を使うと読みやすく、速くなります。さらに、最もシンプルな方法で、csv –

0
import csv 

ab = [['name Belgian Waffles', 
'price $5.95', 
'description Two of our famous Belgian Waffles ', 
'calories 650'], 
['name Chocolate Waffles', 
'price $7.95', 
'description Two of our famous Chocolate Waffles ', 
'calories 1050']] 


l = [] 

for item in ab: 
    d = {kv.split()[0]:' '.join(kv.split()[1:]) for kv in item} 
    l.append(d) 

keys = l[0].keys() 

with open("example.csv", 'w') as o: 
    writer = csv.DictWriter(o,fieldnames=keys) 
    writer.writeheader() 
    writer.writerows(l) 
+0

に書き込むことができる 'pd.Dataframe'を作成します。提案に感謝します。しかし、順序は適切ではありません。毎回ランダムな順序を返します。 – Emmanuel

+0

OrderedDictを実行しようとしましたが、返されたのは ValueError:アンパックする値が多すぎます(予想2)。 – Emmanuel

+0

csvファイルの出力を特定の方法で表示させるには、 'OrderedDict'は必要ありません。 あなたの辞書にあるキーの手前を知っているなら、上記のように 'csv.DictWriter(o、fieldnames = keys)'クラスに 'fieldnames'の' list'をパラメータとして渡すことができます。 'csv.DictWriter'は、' fieldnames'パラメータの順序を尊重し、渡されたキーの順にcsvを書き込みます。 – MetalloyD