3

我目前正在尝试使水文模型(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 组部分。不知道该怎么办!

4

3 回答 3

1

我认为问题出在第二部分的范围定义中... range(3, 5) 表示元素 4 和 5,您想要的可能是 range(2,4) 表示元素 3 和 4。

于 2013-09-28T21:20:59.253 回答
1

问题是您对 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>

问题解决了?

于 2013-09-28T22:25:00.143 回答
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()
于 2013-09-28T21:28:31.823 回答