【问题标题】:How to convert xml file to csv output in python?如何在python中将xml文件转换为csv输出?
【发布时间】:2020-05-19 11:39:24
【问题描述】:

我有一个从我无法控制的数据库中提取的基本 XML 文件。

<?xml version="1.0" encoding="utf-8"?>
<data>
<Job1Start><Time>20200202055415725</Time></Job1Start>
<Job1End><Time>20200202055423951</Time></Job1End>
<Job2Start><Time>20200202055810390</Time></Job2Start>
<Job3Start><Time>20200202055814687</Time></Job3Start>
<Job2End><Time>20200202055819000</Time></Job2End>
<Job3End><Time>20200202055816708</Time></Job3End>
</data>

我希望在 CSV 文件中获得以下输出:

Task    Start               Finish
Job1    20200202055415725   20200202055423951
Job2    20200202055810390   20200202055819000
Job3    20200202055814687   20200202055816708

我尝试了几种方法,以下似乎是我得到的最接近正确输出的方法,但即使这样也不能正常工作:

import xml.etree.ElementTree as ET
import csv

tree = ET.parse('Jobs.xml')
root = tree.getroot()

with open('Output.csv', 'w') as csv_file:
        writer = csv.writer(csv_file, delimiter=',')
        for TaskName in root.findall('Job1Start'):
            starttime = TaskName.find('Time').text
            task = "Job1"
            writer.writerows(zip(task, starttime))
            print("Job1", starttime)

我从中得到的输出如下所示。它的格式不正确,我只能在 Job1 上搜索开始时间:

有人遇到过类似问题吗?

【问题讨论】:

  • 我用当前输出的图像编辑了帖子。格式错误,此代码仅允许我搜索开始时间。我无法加入开始和结束时间。
  • 看起来是zip 引起了你的问题...总是先尝试打印出中间结果。
  • @usr2564301 不,writerows 而不是 writerow 会导致问题。后者需要一个列表列表(或更准确地说是一个可迭代的可迭代对象)并且字符串是可迭代的,因此字符串列表满足要求,但内部“列表”项是单个字符。
  • 是的,我在没有zip 的情况下进行打印,它看起来很好,这就是造成混乱的部分原因。不过很好,感谢您的帮助!

标签: python python-3.x xml csv


【解决方案1】:

writerows 而不是writerow 会导致单字符问题和csv.writerwriterows 需要一个列表列表(或更准确地说是一个可迭代的可迭代对象)并且字符串是可迭代的,因此字符串列表满足要求,但内部“列表”项是单个字符。

csv.writer 根据文档还需要newline='',并且在 Windows 上,当在 Excel 中打开 CSV 时,缺少此参数会显示为行之间的额外空白行。

这里有一个解决方案:

import xml.etree.ElementTree as ET
import csv

tree = ET.parse('Jobs.xml')
root = tree.getroot()

# Use newline='' per csv docs.  This fixes the blanks lines in your output
with open('Output.csv', 'w', newline='') as csv_file:
        writer = csv.writer(csv_file)
        writer.writerow('Task Start Finish'.split())
        for job in range(1,4):
            start = root.find(f'Job{job}Start/Time').text
            end = root.find(f'Job{job}End/Time').text
            # Use writerow not writerows...latter expects list of lists.
            writer.writerow([f'Job{job}',start,end])

输出:

Task,Start,Finish
Job1,20200202055415725,20200202055423951
Job2,20200202055810390,20200202055819000
Job3,20200202055814687,20200202055816708

【讨论】:

    猜你喜欢
    • 2020-11-03
    • 1970-01-01
    • 2019-12-01
    • 2014-11-26
    • 1970-01-01
    • 2019-02-02
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多