使用 Python 将 CSV 行转换为 XML 文件

Posted

技术标签:

【中文标题】使用 Python 将 CSV 行转换为 XML 文件【英文标题】:CSV Rows to XML files using Python 【发布时间】:2012-01-30 04:00:55 【问题描述】:

我的 csv 文件如下所示:

artist,year,id,video_name,new_video_id,file_root_name,video_type
,,,,,,
Clay Aiken,1,clay_aiken,Sorry Seems To Be...,sorry-seems-to-be,02_sc_ca_sorry,FLV
Clay Aiken,1,clay_aiken,Everything I Do (I Do It For You),everything-i-do-i-do-it-for-you,03_sc_ca_everything,FLV
Clay Aiken,1,clay_aiken,A Thousand Days,a-thousand-days,04_sc_ca_thousandda,FLV
Clay Aiken,1,clay_aiken,Here You Come Again,here-you-come-again,05_sc_ca_hereyoucom,FLV
Clay Aiken,1,clay_aiken,Interview,interview,06_sc_ca_intv,FLV

上面的每一行都会生成一个单独的 xml 文件,如下所示(准确地说是 5 个):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE smil PUBLIC "-//W3C//DTD SMIL 2.0//EN" "http://www.w3.org/2001/SMIL20/SMIL20.dtd">
<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
  <head>
    <meta base="rtmp://cp23636.edgefcs.net/ondemand" />
  </head>
  <body>
    <switch>
      <video src="mp4:soundcheck/%year/%id/%file_root_name_256.mp4" system-bitrate="336000"/>
      <video src="mp4:soundcheck/%year/%id/%file_root_name_512.mp4" system-bitrate="592000"/>
      <video src="mp4:soundcheck/%year/%id/%file_root_name_768.mp4" system-bitrate="848000"/>
      <video src="mp4:soundcheck/%year/%id/%file_root_name_1128.mp4" system-bitrate="1208000"/>
    </switch>
  </body>
</smil>

将其命名为 %new_video_id.smil

我已经弄清楚如何解析 csv 文件:

import csv
import sys

f = open(sys.argv[1], 'rU')
reader = csv.reader(f)
for row in reader:
    year = row[1]
    id = row[2]
    file_root_name = row[5]
    print year, id, file_root_name

如何在编写 xml 文件时获取每个变量并包含?

【问题讨论】:

为什么在遍历 csv 时不构建 xml? 不是一个xml,每一行都是一个新的xml。 您需要在内存中构建它还是将每个 xml 文件保存到磁盘? @DavidNeudorfer 你的意思是每行都是video 单个xml文件中的标签? 每一行都将是一个写入磁盘的新 xml 文件。每个文件将使用new_video_id 变量命名 【参考方案1】:

我会从这样的事情开始:

import csv
import sys

from xml.etree import ElementTree
from xml.dom import minidom

video_data = ((256, 336000),
              (512, 592000),
              (768, 848000),
              (1128, 1208000))

with open(sys.argv[1], 'rU') as f:
    reader = csv.DictReader(f)
    for row in reader:
        switch_tag = ElementTree.Element('switch')

        for suffix, bitrate in video_data:
            attrs = 'src': ("mp4:soundcheck/year/id/file_root_name_suffix.mp4"
                             .format(suffix=str(suffix), **row)),
                     'system-bitrate': str(bitrate),
                     
            ElementTree.SubElement(switch_tag, 'video', attrs)
        print minidom.parseString(ElementTree.tostring(switch_tag)).toprettyxml()

基本上在解析csv文件时,使用行中的属性创建一个xml文档,从而一个一个地创建视频标签。

示例输出(一行):

<?xml version="1.0" ?>
<switch>
    <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_256.mp4" system-bitrate="336000"/>
    <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_512.mp4" system-bitrate="592000"/>
    <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_768.mp4" system-bitrate="848000"/>
    <video src="mp4:soundcheck/1/clay_aiken/02_sc_ca_sorry_1128.mp4" system-bitrate="1208000"/>
</switch>

注意:ElementTree 不支持漂亮的打印,所以我使用了PyMOTW 中解释的技巧。

【讨论】:

我正在尝试为每一行创建一个 xml 文件,而不是一个包含所有行的单个 xml 文件。我将如何修改它来做到这一点? @DavidNeudorfer 我已经更新了我的答案来做到这一点。您只需将创建 xml 文件的部分移动到 for 循环中,即可为每一行生成一个新的 xml。 @DavidNeudorfer 我明白了,我已经更改了代码,为每个 csv 行生成多个视频标签。 这正是我所需要的,但我仍然无法在 python 中掌握 xml 操作,并在您的脚本中提出了一个新问题:***.com/questions/8674610/…【参考方案2】:

我会考虑将您的 XML 模板视为格式字符串:创建一个值为 XML 的字符串,替换所有 %year%id%file_root_name。用%s,然后你可以这样做:

 print xml_template % [year, id, file_root_name] * 3

请注意,这只有在 csv 中的数据包含不需要转义的 XML 合法字符时才有效;您需要预处理每个值以将标记字符(&amp;lt;&amp;gt;'")转换为实体(&amp;lt;&amp;gt;&amp;apos;&amp;quot;)。

按照 jcollado 的建议,使用 minidom 和 ElementTree 构建 XML 会更安全。

【讨论】:

以上是关于使用 Python 将 CSV 行转换为 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 将 XML 转换为 CSV

在python中使用argparse将csv转换为xml

使用 Python 或 XSLT 将复杂的 XML 转换为 CSV

使用 XSLT 将 CSV 文件转换为 XML

python [xml文件到voc的csv文件]将voc标签转换为xml格式为csv格式#python #csv #xml

有没有办法使用 KnockoutJS 将 XML 文件转换为 CSV?