Domanda

Sto avendo difficoltà a trovare un buon, esempio di base di come analizzare XML in Python usando Element Tree. Da quello che riesco a trovare, questo sembra essere la libreria più facile da usare per il parsing di XML. Ecco un esempio di XML con cui sto lavorando:

<timeSeriesResponse>
    <queryInfo>
        <locationParam>01474500</locationParam>
        <variableParam>99988</variableParam>
        <timeParam>
            <beginDateTime>2009-09-24T15:15:55.271</beginDateTime>
            <endDateTime>2009-11-23T15:15:55.271</endDateTime>
        </timeParam>
     </queryInfo>
     <timeSeries name="NWIS Time Series Instantaneous Values">
         <values count="2876">
            <value dateTime="2009-09-24T15:30:00.000-04:00" qualifiers="P">550</value>
            <value dateTime="2009-09-24T16:00:00.000-04:00" qualifiers="P">419</value>
            <value dateTime="2009-09-24T16:30:00.000-04:00" qualifiers="P">370</value>
            .....
         </values>
     </timeSeries>
</timeSeriesResponse>

Sono in grado di fare quello che mi serve, utilizzando un metodo hard-coded. Ma ho bisogno del mio codice per essere un po 'più dinamico. Ecco che cosa ha funzionato:

tree = ET.parse(sample.xml)
doc = tree.getroot()

timeseries =  doc[1]
values = timeseries[2]

print child.attrib['dateTime'], child.text
#prints 2009-09-24T15:30:00.000-04:00, 550

Qui ci sono un paio di cose che ho provato, nessuno di loro ha lavorato, riferendo che non riuscivano a trovare TimeSeries (o qualsiasi altra cosa ho provato):

tree = ET.parse(sample.xml)
tree.find('timeSeries')

tree = ET.parse(sample.xml)
doc = tree.getroot()
doc.find('timeSeries')

In sostanza, voglio caricare il file XML, cercare il tag TimeSeries, e scorrere le etichette di valore, restituendo il dateTime e il valore del tag stesso; tutto quello che sto facendo nell'esempio di cui sopra, ma non codifica difficile sezioni di XML mi interessa. Qualcuno mi può indicare qualche esempio, o darmi qualche suggerimento su come lavorare con questo?


Grazie per tutto l'aiuto. Usando entrambi i suggerimenti qui sotto lavorato sul file di esempio che ho fornito, tuttavia, non ha funzionato sul file completo. Ecco l'errore che ottengo dal file vero e proprio quando uso il metodo di Ed Carrel:

 (<type 'exceptions.AttributeError'>, AttributeError("'NoneType' object has no attribute 'attrib'",), <traceback object at 0x011EFB70>)

Ho pensato che ci fosse qualcosa nel file vero e proprio non gli piaceva, così ho incremently rimosso le cose fino a quando ha funzionato. Qui ci sono le linee che ho cambiato:

originally: <timeSeriesResponse xsi:schemaLocation="a URL I removed" xmlns="a URL I removed" xmlns:xsi="a URL I removed">
 changed to: <timeSeriesResponse>

 originally:  <sourceInfo xsi:type="SiteInfoType">
 changed to: <sourceInfo>

 originally: <geogLocation xsi:type="LatLonPointType" srs="EPSG:4326">
 changed to: <geogLocation>

La rimozione degli attributi che hanno 'xsi: ...' risolto il problema. È la 'xsi: ...' non XML valido? Sarà difficile per me per rimuovere questi programmazione. Eventuali arounds di lavoro suggeriti?

Ecco il file XML completo: http://www.sendspace.com/file/lofcpt


Quando ho inizialmente fatto questa domanda, non ero a conoscenza dei namespace in XML. Ora che so cosa sta succedendo, non ho per rimuovere gli attributi "XSI", che sono le dichiarazioni di namespace. Ho appena li includo nelle mie ricerche XPath. Vedere questa pagina per più informazioni spazi dei nomi in lxml.

È stato utile?

Soluzione

Così ho ElementTree 1.2.6 sulla mia casella di oggi, e corse il seguente codice contro il pezzo XML che avete inviato:

import elementtree.ElementTree as ET

tree = ET.parse("test.xml")
doc = tree.getroot()
thingy = doc.find('timeSeries')

print thingy.attrib

ed ha ottenuto la seguente posteriore:

{'name': 'NWIS Time Series Instantaneous Values'}

Sembra aver trovato l'elemento TimeSeries senza bisogno di usare indici numerici.

Che cosa sarebbe utile adesso è sapere cosa si intende quando si dice "non funziona". Dal momento che funziona per me dato lo stesso ingresso, è improbabile che ElementTree è rotto in qualche modo ovvio. Aggiorna il tuo domanda con eventuali messaggi di errore, backtrace, o qualsiasi cosa è possibile fornire per aiutarci ad aiutarti.

Altri suggerimenti

Se ho capito la sua domanda:

for elem in doc.findall('timeSeries/values/value'):
    print elem.get('dateTime'), elem.text

o, se preferite (e se v'è una sola occorrenza di timeSeries/values:

values = doc.find('timeSeries/values')
for value in values:
    print value.get('dateTime'), elem.text

Il metodo findall() restituisce un elenco di tutti gli elementi corrispondenti, mentre i rendimenti find() solo il primo elemento corrispondente. Il primo esempio, il ciclo su tutti gli elementi presenti, le seconde anse sugli elementi secondari dell'elemento values, in questo caso che portano allo stesso risultato.

Non vedo dove sia il problema con non trovare timeSeries proviene comunque. Forse hai solo dimenticato la chiamata getroot()? (Si noti che non si ha realmente bisogno, perché si può lavorare dalla elementtree sé anche, se si modifica l'espressione di percorso per esempio /timeSeriesResponse/timeSeries/values o //timeSeries/values)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top