【问题标题】:python - xml to csv conversionpython - xml到csv的转换
【发布时间】:2018-01-25 22:43:11
【问题描述】:
ab= [['name Belgian Waffles', 'price $5.95', 'description Two of our famous Belgian Waffles ', 'calories 650'] ]

我想使用 python 将此列表解析为表格格式的 CSV 文件

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

注意:列表大小可能会有所不同。这些值可能会有所不同。不应该有硬编码。

有问题的xml是

<?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>

我尝试使用以下 python 脚本首先将其提取到列表中,并以 food 为根

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)

我得到以下列表

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 格式将其写入 CSV

name           price       description       calories
<name given>   <price>     <description>     <calories>

【问题讨论】:

标签: python xml csv


【解决方案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')

编辑:

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')

【讨论】:

  • ValueError:长度不匹配:预期轴有 20 个元素,新值有 4 个元素。它返回以下错误
  • 我认为我在您编辑后的回答更合适:我认为使用lxml 比您的脚本更具可读性和速度。另外,它以最简单的方式构造一个pd.Dataframe,您可以将其写入 csv
【解决方案2】:
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)

【讨论】:

  • 感谢您的建议。但是顺序不对。它每次都返回随机顺序
  • 我尝试提供 OrderedDict 但它返回 ValueError: too many values to unpack (expected 2).
  • 您不需要OrderedDict 以使输出以某种方式出现在 csv 文件中。如果您事先知道字典中有哪些键,您可以将fieldnameslist 作为参数传递给csv.DictWriter(o,fieldnames=keys) 类,就像我在上面所做的那样。 csv.DictWriter 将遵循 fieldnames 参数的顺序,并按照传递给它的键的顺序写入 csv。
猜你喜欢
  • 1970-01-01
  • 2017-04-24
  • 2020-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多