tutorial read open extraer example etree datos con archivo python xml elementtree

read - xml python 3



Analizando XML en Python usando el ejemplo ElementTree (2)

Me está costando encontrar un buen ejemplo básico de cómo analizar XML en Python usando Element Tree. Según lo que puedo encontrar, esta parece ser la biblioteca más fácil de usar para analizar XML. Aquí hay una muestra del XML con el que estoy trabajando:

<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>

Soy capaz de hacer lo que necesito, usando un método codificado. Pero necesito que mi código sea un poco más dinámico. Aquí está lo que funcionó:

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

Aquí hay un par de cosas que he intentado, ninguna de ellas funcionó, informando que no pudieron encontrar timeSeries (o cualquier otra cosa que probé):

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

Básicamente, quiero cargar el archivo xml, buscar la etiqueta timeSeries e iterar a través de las etiquetas de valor, devolviendo dateTime y el valor de la etiqueta; todo lo que estoy haciendo en el ejemplo anterior, pero no codificando con fuerza las secciones de xml que me interesan. ¿Alguien puede indicarme algunos ejemplos o darme algunas sugerencias sobre cómo solucionar esto?

Gracias por toda la ayuda. Sin embargo, al usar las dos sugerencias a continuación trabajadas en el archivo de muestra que proporcioné, no funcionaron en el archivo completo. Este es el error que obtengo del archivo real cuando uso el método de Ed Carrel:

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

Pensé que había algo en el archivo real que no me gustó, así que de forma incremental quité las cosas hasta que funcionó. Estas son las líneas que cambié:

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>

Eliminar los atributos que tienen ''xsi: ...'' solucionó el problema. ¿El XML ''xsi: ...'' no es válido? Será difícil para mí eliminar estos programáticamente. ¿Alguna solución sugerida?

Aquí está el archivo XML completo: http://www.sendspace.com/file/lofcpt

Cuando originalmente hice esta pregunta, no conocía los espacios de nombres en XML. Ahora que sé lo que está pasando, no tengo que eliminar los atributos "xsi", que son las declaraciones del espacio de nombres. Simplemente los incluyo en mis búsquedas xpath. Consulte esta página para obtener más información sobre los espacios de nombres en lxml.


Así que tengo ElementTree 1.2.6 en mi caja ahora, y ejecuté el siguiente código contra el fragmento de XML que publicaste:

import elementtree.ElementTree as ET tree = ET.parse("test.xml") doc = tree.getroot() thingy = doc.find(''timeSeries'') print thingy.attrib

y obtuve lo siguiente:

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

Parece haber encontrado el elemento timeSeries sin necesidad de usar índices numéricos.

Lo que sería útil ahora es saber a qué te refieres cuando dices "no funciona". Como funciona para mí con la misma información, es poco probable que ElementTree se rompa de alguna manera obvia. Actualice su pregunta con cualquier mensaje de error, trazas inversas o cualquier cosa que pueda proporcionar para ayudarnos a ayudarlo.


Si entiendo tu pregunta correctamente:

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

o si lo prefiere (y si solo hay una ocurrencia de timeSeries/values :

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

El método findall() devuelve una lista de todos los elementos coincidentes, mientras que find() solo devuelve el primer elemento coincidente. El primer ejemplo recorre todos los elementos encontrados, los segundos bucles sobre los elementos secundarios del elemento de values , en este caso conduce al mismo resultado.

Sin embargo, no veo de dónde viene el problema de no encontrar timeSeries . ¿Tal vez olvidaste la llamada getroot() ? (tenga en cuenta que realmente no lo necesita porque también puede trabajar desde el árbol de elementos si cambia la expresión de ruta a, por ejemplo, /timeSeriesResponse/timeSeries/values o //timeSeries/values )