2016-02-26 3 views
0

Я загрузил образец XML-данных с веб-сайта и хотел его прочитать на Python. Образец приведен ниже:Python: чтение XML с несколькими значениями в одном теге

<Locations> 
    <Location elevation="933.0" id="3072" latitude="56.879" longitude="-3.42" name="Cairnwell" nationalPark="Cairngorms National Park" region="ta" unitaryAuthArea="Perth and Kinross" /> 
    <Location elevation="134.0" id="3088" latitude="56.852" longitude="-2.264" name="Inverbervie" region="gr" unitaryAuthArea="Aberdeenshire" /> 
    <Location elevation="4.0" id="3094" latitude="57.698" longitude="-2.121" name="Rosehearty Samos" region="gr" unitaryAuthArea="Aberdeenshire" /> 
    <Location elevation="35.0" id="3144" latitude="56.326" longitude="-3.729" name="Strathallan" region="ta" unitaryAuthArea="Perth and Kinross" /> 
    <Location elevation="277.0" id="3152" latitude="55.862" longitude="-3.875" name="Salsburgh" region="st" unitaryAuthArea="North Lanarkshire" /> 
    <Location elevation="57.0" id="3166" latitude="55.928" longitude="-3.343" name="Edinburgh/Gogarbank" region="dg" unitaryAuthArea="Edinburgh" /> 
    <Location elevation="16.0" id="3204" latitude="54.0849" longitude="-4.6321" name="Ronaldsway" region="nw" /> 
    <Location elevation="124.0" id="3210" latitude="54.5181" longitude="-3.615" name="St. Bees Head" region="nw" unitaryAuthArea="Cumbria" /> 
    <Location elevation="28.0" id="3220" latitude="54.933" longitude="-2.963" name="Carlisle" region="nw" unitaryAuthArea="Cumbria" /> 
    <Location elevation="285.0" id="3224" latitude="55.05" longitude="-2.553" name="Spadeadam" region="nw" unitaryAuthArea="Cumbria" /> 
    <Location elevation="32.0" id="3257" latitude="54.296" longitude="-1.53" name="Leeming" region="yh" unitaryAuthArea="North Yorkshire" /> 
    <Location elevation="33.0" id="3261" latitude="54.134" longitude="-1.414" name="Dishforth Airfield" region="yh" unitaryAuthArea="North Yorkshire" /> 
    <Location elevation="7.0" id="3382" latitude="53.867" longitude="-0.433" name="Leconfield Sar" region="yh" unitaryAuthArea="East Riding of Yorkshire" /> 
    <Location elevation="3.0" id="3392" latitude="53.088" longitude="0.274" name="Wainfleet" region="em" unitaryAuthArea="Lincolnshire" /> 
    <Location elevation="4.0" id="6" latitude="50.9561" longitude="0.9392" name="Lydd" region="se" unitaryAuthArea="Kent" /> 
    <Location elevation="24.0" id="22" latitude="53.5797" longitude="-0.3472" name="Humberside Airport" region="yh" unitaryAuthArea="North Lincolnshire" /> 
    <Location elevation="25.0" id="33" latitude="60.4322" longitude="-1.2992" name="Scatsta" region="os" unitaryAuthArea="Shetland Islands" /> 
    <Location elevation="7.0" id="3006" latitude="60.447" longitude="-1.277" name="Sella Ness" region="os" unitaryAuthArea="Shetland Islands" /> 
    <Location elevation="57.0" id="3008" latitude="59.527" longitude="-1.628" name="Fair Isle" region="os" unitaryAuthArea="Shetland Islands" /> 
    <Location elevation="18.0" id="3037" latitude="57.257" longitude="-5.809" name="Skye/Lusa (Samos)" region="he" unitaryAuthArea="Highland" /> 
    <Location elevation="773.0" id="3039" latitude="57.4175" longitude="-5.689" name="Bealach Na Ba" region="he" unitaryAuthArea="Highland" /> 
    <Location elevation="1130.0" id="3041" latitude="56.822" longitude="-4.97" name="Aonach Mor" region="he" unitaryAuthArea="Highland" /> 
    <Location elevation="99.0" id="99003" latitude="58.167" longitude="-4.733" name="Cassley" region="he" unitaryAuthArea="Highland" /> 
    <Location elevation="48.0" id="99025" latitude="52.833" longitude="-1.25" name="Sutton Bonington" region="em" unitaryAuthArea="Nottinghamshire" /> 
    <Location elevation="89.0" id="99057" latitude="52.017" longitude="-0.6" name="Woburn" region="ee" unitaryAuthArea="Central Bedfordshire" /> 
    <Location elevation="140.0" id="99062" latitude="52.456" longitude="-1.9262" name="Winterbourne" region="wm" unitaryAuthArea="West Midlands Conurbation" /> 
    <Location elevation="41.0" id="99078" latitude="52.4" longitude="-0.233" name="Monks Wood" region="ee" unitaryAuthArea="Cambridgeshire" /> 
    <Location elevation="43.0" id="99086" latitude="54.667" longitude="-5.75" name="Helens Bay" region="ni" unitaryAuthArea="County Down" /> 
    <Location elevation="20.0" id="3980" latitude="55.366" longitude="-7.333" name="Malin Head" /> 
    <Location elevation="95.0" id="3405" latitude="52.789" longitude="-4.742" name="Aberdaron" region="wl" unitaryAuthArea="Gwynedd" /> 
    <Location elevation="163.0" id="3409" latitude="52.917" longitude="-3.583" name="Bala" region="wl" unitaryAuthArea="Gwynedd" /> 
    <Location elevation="72.0" id="3414" latitude="52.794" longitude="-2.663" name="Shawbury" region="wm" unitaryAuthArea="Shropshire" /> 
    <Location elevation="138.0" id="3453" latitude="52.727" longitude="-0.654" name="Cottesmore" region="em" unitaryAuthArea="Rutland" /> 
    <Location elevation="21.0" id="3482" latitude="52.651" longitude="0.569" name="Marham" region="ee" unitaryAuthArea="Norfolk" /> 
    <Location elevation="14.0" id="3496" latitude="52.686" longitude="1.693" name="Hemsby" region="ee" unitaryAuthArea="Norfolk" /> 
    <Location elevation="63.0" id="3503" latitude="52.344" longitude="-3.947" name="Trawsgoed" region="wl" unitaryAuthArea="Ceredigion" /> 
    <Location elevation="307.0" id="3507" latitude="52.063" longitude="-3.614" name="Sennybridge" region="wl" unitaryAuthArea="Powys" /> 
    <Location elevation="44.0" id="3604" latitude="51.708" longitude="-5.055" name="Milford Haven C.B." region="wl" unitaryAuthArea="Pembrokeshire" /> 
    <Location elevation="59.0" id="3628" latitude="51.521" longitude="-2.576" name="Filton" region="sw" unitaryAuthArea="South Gloucestershire" /> 
    <Location elevation="81.0" id="3649" latitude="51.758" longitude="-1.576" name="Brize Norton" region="se" unitaryAuthArea="Oxfordshire" /> 
    <Location elevation="40.0" id="3672" latitude="51.548" longitude="-0.415" name="Northolt" region="se" unitaryAuthArea="Greater London" /> 
    <Location elevation="348.0" id="3710" latitude="51.087" longitude="-3.608" name="Liscombe" nationalPark="Exmoor National Park" region="sw" unitaryAuthArea="Somerset" /> 
    </Locations> 

Я хочу, чтобы разобрать этот файл таким образом, что она выглядит следующим образом:

Location Elevation id latitude longitude  name   nationalpark  region unitaryAuthArea 
     933.0  3072 56.879 -3.42  Cairnwell Cairngorms National Park ta  Perth and Kinross 
     134.0  3088 56.852 -2.264 Inverbervie        gr  Aberdeenshire 

и я действительно хочу эти данные в этом формате, так что он может быть экспортирована в формате CSV. я действительно новичок в Python XML Parsing, хотя ранее цитировал аналогичную проблему, но до этого никогда не получал пакет XML.ETREE.ELEMENTTREE. Код я пытался до сих пор даются как:

import xml.etree.ElementTree as ET 
tree = ET.parse('sitelist.xml') 
regions = tree.getroot()[0] 
for region in regions.iter('name'): 
    print region.tag, region.attrib 

Может кто-нибудь мне помочь в крекинге этой проблемы это поможет мне в моих академических исследованиях.

ответ

1

ET элементы перебора своих детей. Специальная функция .iter() выполняет итерацию элементов данного имени во всем поддереве. Его ненужное здесь и будет работать, только если вы ищете «Местоположение» вместо «имя». В вашем примере <Locations> - это корень дерева, поэтому простое повторение корня получит нужные вам элементы.

Затем вы должны извлечь нужные атрибуты. Вы можете просто положить их в список и использовать get, чтобы получить их. Наконец, подключите csv.writer, и у вас все получилось.

редактировать: счет юникод символов

import xml.etree.ElementTree as ET 
import csv 
import codecs 

fields = ['id', 'latitude', 'longitude', 'name', 'nationalPark', 'region', 
    'unitaryAuthArea'] 

with open('output.csv', 'wb') as fp: 
    writer = csv.writer(fp) 
    writer.writerow(fields) 
    tree = ET.parse('test.xml') 
    # from your example Locations is the root and Location is the first level 
    for elem in tree.getroot(): 
     writer.writerow([(elem.get(name) or '').encode('utf-8') 
      for name in fields]) 
+0

ошибка: Traceback (самый последний вызов последним): Файл "C: /Python27/sitelist.py", строка 13, в writer.writerow ([elem.get (name) для имени в полях]) UnicodeEncodeError: кодек 'ascii' не может кодировать символ u '\ xf2' в позиции 16: порядковый номер не в диапазоне (128) –

+0

csv writer не нравится Юникод. Пока вы нормально записываете csv-файл, закодированный utf-8, обновление, которое я только что применил, работает. – tdelaney

+0

Выходной файл не содержит национальных парков, я не уверен, почему это не сработало. Можете ли вы мне помочь? –