将 CSV 转换为 XML
Posted
技术标签:
【中文标题】将 CSV 转换为 XML【英文标题】:Converting CSV to XML 【发布时间】:2013-10-04 23:41:33 【问题描述】:我目前正在尝试使水文模型 (HBV-light) 的输入文件与外部校准软件 (PEST) 兼容。 HBV-light 要求它的输入文件是 XML 格式,而 PEST 只能读取文本文件。我的问题与编写一个脚本有关,该脚本将自动将 PEST 编写的参数集(以 CSV 格式)转换为 HBV-light 可以读取的 XML 文件。
这是一个可以由 PEST 编写的文本文件的简短示例:
W,X,Y,Z
1,2,3,4
这就是我尝试组织 XML 文件的方式:
<Parameters>
<GroupA>
<W>1</W>
<X>2</X>
</GroupA>
<GroupB>
<Y>3</Y>
<Z>4</Z>
</GroupB>
</Parameters>
我没有太多的编程经验,但这是我到目前为止写的一个python代码:
import csv
csvFile = 'myCSVfile.csv'
xmlFile = 'myXMLfile.xml'
csvData = csv.reader(open(csvFile))
xmlData = open(xmlFile, 'w')
xmlData.write('<?xml version="1.0" encoding="utf-8"?>' + "\n")
# there must be only one top-level tag
xmlData.write('<Catchment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">' + "\n")
xmlData.write('<CatchmentParamters>' + "\n")
rowNum = 0
for row in csvData:
if rowNum == 0:
tags = row
# replace spaces w/ underscores in tag names
for i in range(0, 2):
tags[i] = tags[i].replace(' ', '_')
else:
for i in range(0, 2):
xmlData.write(' ' + '<' + tags[i] + '>' \
+ row[i] + '</' + tags[i] + '>' + "\n")
rowNum +=1
xmlData.write('</CatchmentParameters>' + "\n")
xmlData.write('<VegetationZone>' + "\n")
xmlData.write('<VegetationZoneParameters>' + "\n")
rowNum = 0
for row in csvData:
if rowNum == 0:
tags = row
# replace spaces w/ underscores in tag names
for i in range(3, 5):
tags[i] = tags[i].replace(' ', '_')
else:
for i in range(3, 5):
xmlData.write(' ' + '<' + tags[i] + '>' \
+ row[i] + '</' + tags[i] + '>' + "\n")
rowNum +=1
xmlData.write('</VegetationZoneParameters>' + "\n")
xmlData.write('</VegetationZone>' + "\n")
xmlData.write('</Catchment>' + "\n")
xmlData.close()
我可以编写 A 组(或特别是 CathmentParameters),但未编写 B 组部分。不知道该怎么办!
【问题讨论】:
作为“第一次问题”,这个写得很好!我没有给你一个快速的答案 - 但请看一下***.com/questions/3605680/… 我确实有一个缓慢的答案...见下文。 您将来可能会考虑的一件事-您的代码似乎处理了两次文件,就好像您希望在任何 Vegetation 参数之前获得所有 Catchment 参数-这就是我写答案的方式。看来(从接受的答案)您打算做一些不同的事情。具有两行数据的示例将显示差异。请记住,帮助 SO 的人无法读心 - 他们只能根据您提供的信息进行推断。 【参考方案1】:我认为循环是错误的。 试试这是否适合你
#! /usr/bin/env python
# coding= utf-8
import csv
csvFile = 'myCSVfile.csv'
xmlFile = 'myXMLfile.xml'
csvData = csv.reader(open(csvFile))
xmlData = open(xmlFile, 'w')
xmlData.write('<?xml version="1.0" encoding="utf-8"?>' + "\n")
# there must be only one top-level tag
xmlData.write('<Catchment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">' + "\n")
xmlData.write('<CatchmentParamters>' + "\n")
rowNum = 0
for row in csvData:
if rowNum == 0:
tags = row
# replace spaces w/ underscores in tag names
for i in range(0, 2):
tags[i] = tags[i].replace(' ', '_')
else:
for i in range(0, 2):
xmlData.write(' ' + '<' + tags[i] + '>' \
+ row[i] + '</' + tags[i] + '>' + "\n")
xmlData.write('</CatchmentParameters>' + "\n")
xmlData.write('<VegetationZone>' + "\n")
xmlData.write('<VegetationZoneParameters>' + "\n")
for i in range(2, 4):
xmlData.write(' ' + '<' + tags[i] + '>' \
+ row[i] + '</' + tags[i] + '>' + "\n")
xmlData.write('</VegetationZoneParameters>' + "\n")
xmlData.write('</VegetationZone>' + "\n")
rowNum +=1
xmlData.write('</Catchment>' + "\n")
xmlData.close()
【讨论】:
非常感谢您解决我遇到的问题!这是解决我遇到的问题的好方法。仍然是编程的新手,因此仍在学习循环的工作原理,您更改我的代码的方式已经阐明了问题所在! 我想你发现你的第一个标签CatchmentParamters
拼写错误。【参考方案2】:
我认为问题在于您在第二部分中的范围定义... range(3, 5) 表示元素 4 和 5,您想要的可能是 range(2,4) 表示元素 3 和 4。
【讨论】:
当然。仍然习惯于索引。谢谢!【参考方案3】:问题是您对 csv 文件的内容进行了两次迭代——看来您需要在第一次循环之后“倒回”。还有一个小的索引问题,第二个范围需要是 range(2,4)
而不是 range(3,5)
,正如已经指出的那样。
我创建了一段似乎可以工作的代码。正确理解 Python 的人可能会对其进行改进。注意 - 我添加了一些打印语句来说服自己我理解正在发生的事情。如果您没有再次打开csvFile
(在“开始第二个for 循环”时),则不会打印任何行。这就是你的线索,这就是问题所在。
import csv
csvFile = 'myCSVfile.csv'
xmlFile = 'myXMLfile.xml'
csvData = csv.reader(open(csvFile))
xmlData = open(xmlFile, 'w')
xmlData.write('<?xml version="1.0" encoding="utf-8"?>' + "\n")
# there must be only one top-level tag
xmlData.write('<Catchment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">' + "\n")
xmlData.write('<CatchmentParamters>' + "\n")
rowNum = 0
for row in csvData:
print "row is ", row
if rowNum == 0:
tags = row
# replace spaces w/ underscores in tag names
for i in range(0, 2):
tags[i] = tags[i].replace(' ', '_')
else:
for i in range(0, 2):
xmlData.write(' ' + '<' + tags[i] + '>' \
+ row[i] + '</' + tags[i] + '>' + "\n")
rowNum +=1
xmlData.write('</CatchmentParameters>' + "\n")
xmlData.write('<VegetationZone>' + "\n")
xmlData.write('<VegetationZoneParameters>' + "\n")
rowNum = 0
print "starting the second for loop"
csvData = csv.reader(open(csvFile))
for row in csvData:
print "row is now ", row
if rowNum == 0:
tags = row
# replace spaces w/ underscores in tag names
for i in range(2, 4):
tags[i] = tags[i].replace(' ', '_')
else:
for i in range(2, 4):
xmlData.write(' ' + '<' + tags[i] + '>' \
+ row[i] + '</' + tags[i] + '>' + "\n")
rowNum +=1
xmlData.write('</VegetationZoneParameters>' + "\n")
xmlData.write('</VegetationZone>' + "\n")
xmlData.write('</Catchment>' + "\n")
xmlData.close()
将上述内容与您提供的小测试文件一起使用会生成以下 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<Catchment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CatchmentParamters>
<W>1</W>
<X>2</X>
</CatchmentParameters>
<VegetationZone>
<VegetationZoneParameters>
<Y>3</Y>
<Z>4</Z>
</VegetationZoneParameters>
</VegetationZone>
</Catchment>
问题解决了吗?
【讨论】:
是的!非常感谢您花时间玩它!似乎(至少)有两种简单的方法可以解决这个问题。我仍然在处理循环,所以这是问题出现的地方是有道理的。 很高兴您得到了解决方案!以上是关于将 CSV 转换为 XML的主要内容,如果未能解决你的问题,请参考以下文章