2016-11-19 10 views
4

У меня есть фрагмент кода, который извлекает координаты из файла KML. Он прекрасно работает и печатает на экране то, как я хочу, чтобы он печатался в CSV-файле. Однако, когда я пытаюсь записать его в CSV-файл, результирующий файл пуст.Запись списка в файл CSV

Я пробовал как метод ниже, так и стандартный метод вывода текста с использованием .write и .writerows. Все имеют одинаковый результат.

Вот это KML я использую:

<?xml version="1.0" encoding="UTF-8"?> 
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"> 
<Document> 
    <name>Test3.kml</name> 
    <Style id="s_ylw-pushpin"> 
     <IconStyle> 
      <scale>1.1</scale> 
      <Icon> 
       <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href> 
      </Icon> 
      <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/> 
     </IconStyle> 
    </Style> 
    <Style id="s_ylw-pushpin_hl"> 
     <IconStyle> 
      <scale>1.3</scale> 
      <Icon> 
       <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href> 
      </Icon> 
      <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/> 
     </IconStyle> 
    </Style> 
    <StyleMap id="m_ylw-pushpin"> 
     <Pair> 
      <key>normal</key> 
      <styleUrl>#s_ylw-pushpin</styleUrl> 
     </Pair> 
     <Pair> 
      <key>highlight</key> 
      <styleUrl>#s_ylw-pushpin_hl</styleUrl> 
     </Pair> 
    </StyleMap> 
    <Placemark> 
     <name>Untitled</name> 
     <styleUrl>#m_ylw-pushpin</styleUrl> 
     <LineString> 
      <tessellate>1</tessellate> 
      <coordinates> 
       -117.2983479390361,33.27144940863937,0 -117.2979479084534,33.27158154479859,0 -117.2974695164833,33.27172038778199,0 -117.2975027748323,33.27194103134417,0 -117.297514618297,33.27194834552386,0 -117.2979065026131,33.27210103585357,0 -117.2980671096438,33.27197757139673,0 -117.2980506390891,33.27176546338881,0 -117.2983889177018,33.27174732829762,0 -117.2985056013534,33.27196820309105,0 -117.2984607071796,33.27217535203514,0 -117.2982982520078,33.2722451382993,0 -117.2982714656408,33.2722496045722,0 -117.297926137081,33.27225329696987,0 -117.2979181624345,33.27225324047765,0 -117.297660871735,33.27222714260547,0 -117.2976362532899,33.2722186164706,0 -117.2974159727989,33.27218328409937,0 -117.2974081729552,33.27218350960742,0 -117.2970860609136,33.27208829299941,0 -117.2968393500826,33.27207716108421,0 -117.2967459496535,33.27216774204006,0 -117.2966603938058,33.27233920748802,0 -117.2969907889174,33.27237357387524,0 -117.2970232333844,33.27237306198914,0 -117.2973444433226,33.27239693646774,0 -117.297751764355,33.27242613992279,0 -117.2981731050047,33.27243373303686,0 -117.2981813185804,33.27243372905114,0 -117.2985617246156,33.2723816290589,0 -117.2987498163436,33.27248971415388,0 -117.2987694564539,33.27262188734785,0 -117.2985436721398,33.27267540671544,0 -117.2985270445518,33.27267612619851,0 -117.2981490803383,33.27268345629938,0 -117.2981145841072,33.2726829556605,0 -117.2977420026904,33.27265933276826,0 -117.2977334907908,33.27265936075214,0 -117.2977079525845,33.27265943947727,0 -117.297690884793,33.27265933069783,0 -117.2973143742666,33.2726410594433,0 -117.2972972842265,33.27263660852098,0 -117.2972803621663,33.27263663588342,0 -117.2969673713573,33.27262125275644,0 -117.296756583612,33.27260864705382,0 -117.2965634725893,33.27264899681126,0 -117.2965301429721,33.27279607660442,0 -117.296929900768,33.27282274189361,0 -117.2972917056901,33.27281884120617,0 -117.2975482260676,33.27280094439733,0 -117.2979485409129,33.27281652227333,0 -117.2983940432828,33.2728392485114,0 -117.2987809571886,33.27284381722371,0 
      </coordinates> 
     </LineString> 
    </Placemark> 
</Document> 
</kml> 

И код:

from xml.dom import minidom 
import csv 

xmldoc = minidom.parse("Test.kml") 

kml = xmldoc.getElementsByTagName("kml")[0] 

document = kml.getElementsByTagName("Document")[0] 

placemarks = document.getElementsByTagName("Placemark") 

for placemark in placemarks: 
    coords = placemark.getElementsByTagName("coordinates")[0].firstChild.data 

    list = coords.split(",") 
    for items in list: 
     item = items.split(",") 
     for allitems in item: 
      latlon = allitems.replace("0 ","") 
      latlon = latlon.strip() 
      print(latlon) # <-- Printing to the screen works fine 
      with open("Output.csv", "w") as output: 
       writer = csv.writer(output, delimiter='\n') 
       writer.writerow(latlon) 

**** решаемые **** Final рабочего решения заключается в следующем:

with open("Output.csv", "w") as text_file:    # open the file first 
    #writer = csv.writer(output, delimiter='\n')  # and get ready to write 

    for placemark in placemarks: 
     coords = placemark.getElementsByTagName("coordinates")[0].firstChild.data 

     list = coords.split(",") 
     for items in list: 
      item = items.split(",") 
      for allitems in item: 
       latlon = allitems.replace("0 ","") 
       latlon = latlon.strip() 
       print(latlon) # <-- Printing to the screen works fine 
       text_file.write(latlon + '\n')  # Write the row to the already-open file 

Я отказался от метода csv и пошел с выходом текстового файла, просто переименовав его в csv. Я получаю результат, который мне нужен. Благодаря всем, что способствовало.

+2

Вы понимаете, что вы повторно открываете файл в режиме 'w'rite каждый раз через цикл? – jonrsharpe

+0

jonrsharpe и Oliver W. Верьте или нет, я переделал несколько разных способов, прежде чем закончить здесь. Вы оба сразу открываете файл только один раз. Очевидная ошибка. – user3108489

ответ

4

with и writer= должно происходить раз в начале цикла. Как и сейчас, вы повторно создаете файл для каждого элемента, отбрасывая последний элемент.

with open("Output.csv", "w") as output:    # open the file first 
    writer = csv.writer(output, delimiter='\n')  # and get ready to write 

    for placemark in placemarks: 
     coords = placemark.getElementsByTagName("coordinates")[0].firstChild.data 

     list = coords.split(",") 
     for items in list: 
      item = items.split(",") 
      for allitems in item: 
       latlon = allitems.replace("0 ","") 
       latlon = latlon.strip() 
       print(latlon) # <-- Printing to the screen works fine 
       writer.writerow([latlon])  # Write the row to the already-open file 
         # EDIT 2^ ^

Edit Теперь может быть другой вопрос: это выглядит как latlon это строка, но writerow ожидает список элементов и заполняет запятые между элементами автоматически. Возможно, вам понадобится print(latlon + ',', file=output) вместо writer.writerow в зависимости от вашего конкретного варианта использования.

Edit 2 Использование [latlon] вместо latlon, чтобы получить всю строку на одной строке вместо одного символа в строке. Скобки представляют собой список из одного элемента, а не строки, которая ведет себя в этом контексте, как список его символов, по одному за раз.

+0

* «Код, который следует после редактирования» * - вместо этого вы могли бы завершить ответ, прежде чем нажимать «Опубликовать»? – jonrsharpe

+2

Но тогда у них не было бы первого ответа. ;) –

+0

@cxw Это в конечном итоге привело меня туда, где я должен был быть. Спасибо. Ваш пример, как есть, помещает каждый символ каждого элемента в список в новой строке. Кроме того, печать (latlon + ',', file = output) привела к недопустимой синтаксической ошибке, выделив значение "=" – user3108489