【问题标题】:python .xml and .csv files manipulationpython .xml 和 .csv 文件操作
【发布时间】:2019-05-30 13:15:43
【问题描述】:

我将 .xml 文件转换为 .csv。在.xml文件中有一些来自txtDescricao这种类型列的值:"Logistics, Search and Support."因此,当我读取文件时,pandas将Logistics之后的逗号解释为列分隔符,并抛出其余文本向前。我正在尝试使用以下代码解决此问题:

in_file = 'dados_limpos_2018.csv'
out_file = 'dados_2018.csv'
output = open(out_file, 'w')
with open(in_file, 'r') as source:
    for line in source:
    # split by semicolon
        data = line.strip().split(';')             
    # remove all quotes found
        data = [t.replace('"','') for t in data]
        for item in data[:-1]:
            item.replace(',', '')
            output.write(''.join(['', item, '',',']))
            # write the last item separately, without the trailing ';'
        output.write(''.join(['"', item, '"']))
        output.write('\n')
output.close()

然而,在这一行中,python 已经将逗号解释为分隔符并将其转换为分号。在这里我想知道:有什么方法可以在 .csv 文件中处理这个问题,或者我必须在 .xml 到 .csv 的转换中这样做吗? .cs 文件示例

name, number, sgUF, txtDescricao, year
Romario, 15, RJ, Consultoria, 2018
Ronaldo, 9, RJ, Logistics, Search and Support, 2018

.xml 文件示例:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
    <dados>
          <despesa>
                  <name>Romario</name>
                  <number>15</number>
                  <sgUF>RJ</sgUF>
                  <txtDescricao>Consultoria</txtDescricao>
                  <year>2018</year>
           </despesa>

           <despesa>
                  <name>Ronaldo</name>
                  <number>9</number>
                  <sgUF>RJ</sgUF>
                  <txtDescricao>Logistics, Search and Support</txtDescricao>
                  <year>2018</year>
           </despesa>
     </dados>
</xml>

注意:原始文件太大,无法在电子表格编辑器中打开。

【问题讨论】:

  • 你的 .xml 文件在哪里读入代码?仅分配 .csv 文件。另外,熊猫在哪里使用?期望的输出是什么?请edit您的帖子为minimal reproducible example。确保您发布的内容可以完全运行(包括 import 行)以在空 Python 环境中重现您的问题。

标签: python xml csv


【解决方案1】:

我修改了您的函数以处理txtDescricao 列中的这些情况。

ncols= 5
index = 3
in_file = 'dados_limpos_2018.csv'
out_file = 'dados_2018.csv'
output = open(out_file, 'w')
with open(in_file, 'r') as source:
     for line in source:
         # split by colon
         data = line.strip().split(',')
         # Change third element
         data_len = len(data)
         if  data_len > ncols:
             # Join all elements
             data[index] = ''.join(data[index:index + 1 + (data_len - ncols)])
             data[index + 1:] = data[index + 1 + data_len - ncols:]
         # Write columns
         output.write(','.join(data[:ncols]))
         output.write('\n')
 output.close()

输入文件:

name, number, sgUF, txtDescricao, year
Romario, 15, RJ, Consultoria, 2018
Ronaldo, 9, RJ, Logistics, Search and Support, 2018

输出文件:

name, number, sgUF, txtDescricao, year
Romario, 15, RJ, Consultoria, 2018
Ronaldo, 9, RJ, Logistics Search and Support, 2018

OBS.:我假设这个问题只出现在txtDecricao 列中。

【讨论】:

  • 为什么'如果 len(data) > 5:' ?
  • 检查该行是否有超过 5 个逗号分隔值(列数)。如果发生这种情况,我假设txtDescricao 中的值包含逗号,并且在data 列表中产生了5 个以上的值。
  • 原文件有28列,逗号的那一列是8。我做了替换:你代码中的3代表我的8; 4 => 9; 5 => 10;错误仍然存​​在。
  • 我把代码改成了更一般的情况,现在应该更清楚了。
  • 知道了。但是,您正在合并列名,请输入:txtDescricaoyear
【解决方案2】:

如果您共享您的 xml 文件,那就太好了。

根据提供的信息,

如果您的 xml 文件数据具有 , 作为值,请使用不同的分隔符(分号、制表符、空格)来形成您的 csv 文件。 或者 只需将,在XML文件中替换为null,然后转换即可。

在这两种情况下,您都应该在从 xml 转换为 csv 时处理这个问题。使用 csv -> csv 将难以实现,并且 , 的数量将是不可预测的。

编辑 1:

我建议使用来自 lxml 的 objectify。 不要忘记从您的 xml 中删除 &lt;?xml version="1.0" encoding="UTF-8"?&gt;。 解决方法如下。

from lxml import objectify
import csv

file_xml = open('d:\\path\\to\\xml.xml','r')
converted_csv_file = open("converted.csv","w")
xml_string = file_xml.read()
xml_object = objectify.fromstring(xml_string)
csvwriter = csv.writer(converted_csv_file, delimiter=',',lineterminator = '\n')
count = 0
for row in xml_object.dados.despesa:
    if count == 0:
        csvwriter.writerow([row.name.tag,row.number.tag,row.sgUF.tag,row.txtDescricao.tag,row.year.tag])
    csvwriter.writerow([row.name.text,row.number.text,row.sgUF.text,row.txtDescricao.text.replace(',',''),row.year.text])
    count += 1

你可以通过安装lxml

pip install lxml

【讨论】:

  • 我正在尝试这个并得到以下错误:没有这样的孩子:名字
  • 它区分大小写,因此您在 xml 中有子“名称”或“名称”
猜你喜欢
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-27
  • 1970-01-01
  • 2021-05-24
  • 1970-01-01
相关资源
最近更新 更多