62 votes

L'analyse de XML en Python à l'aide de ElementTree exemple

Je vais avoir un moment difficile de trouver un bon exemple de base de l'analyse de XML en python à l'aide de l'Élément de l'Arbre. De ce que je peux trouver, cela semble être la méthode la plus simple de la bibliothèque à utiliser pour l'analyse de XML. Voici un exemple de XML, je travaille avec:

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

Je suis capable de faire ce dont j'ai besoin, à l'aide d'un codée en dur de la méthode. Mais j'ai besoin de mon code pour être un peu plus dynamique. Voici ce qui a fonctionné:

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

Voici un couple de choses que j'ai essayé, aucun d'entre eux travaillaient, déclarant qu'ils ne pouvaient pas trouver timeSeries (ou d'autre chose, j'ai essayé):

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

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

Fondamentalement, je veux charger le fichier xml, recherche pour l'timeSeries tag, et parcourir la valeur des balises, de retourner la date et la valeur de la balise elle-même; tout ce que je fais dans l'exemple ci-dessus, mais pas le codage en dur des sections de xml, je suis intéressé. Quelqu'un peut-il m'indiquer quelques exemples, ou me donner quelques suggestions sur la façon de travailler à travers cela? Merci pour votre aide

Mise à JOUR (11/24/09): Merci pour toute l'aide. En utilisant à la fois des solutions ci-dessous travaillé sur l'exemple de fichier que j'ai à condition, toutefois, qu'elles ne travaillent pas sur la totalité du fichier. Voici l'erreur que je reçois de la réelle fichier lorsque j'utilise Ed Carrel de la méthode:

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

Je disais qu'il y avait quelque chose dans le fichier réel, il n'aime pas, donc je incremently choses enlevées jusqu'à ce qu'il a travaillé. Voici les lignes que j'ai changé:

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>

En supprimant les attributs qui ont " xsi:...' résolu le problème. Est le " xsi:...' pas valide XML? Ça va être dur pour moi de supprimer ces par programmation. Toute proposition de solutions?

Voici tout le fichier XML: http://www.sendspace.com/file/lofcpt

Merci encore

Casey

Mise à JOUR (11/24/11)

Quand j'ai d'abord posé cette question, j'étais pas au courant des espaces de nommage dans XML. Maintenant que je sais ce qu'il se passe, je n'ai pas à supprimer le "xsi" des attributs, qui sont les déclarations d'espace de noms. Je viens de les inclure dans mon xpath recherches. Voir cette page pour plus d'informations sur les espaces de noms dans lxml.

46voto

Ed Carrel Points 1823

J'ai donc ElementTree 1.2.6 sur ma boîte maintenant, et a couru le code suivant sur le XML morceau que vous avez posté:

import elementtree.ElementTree as ET

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

print thingy.attrib

et a obtenu les éléments suivants:

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

Il semble avoir trouvé la timeSeries élément sans avoir à utiliser des indices numériques.

Ce qui serait utile maintenant est de savoir ce que vous voulez dire quand vous dites "ça ne fonctionne pas." Puisque ça marche pour moi, compte tenu de la même entrée, il est peu probable que ElementTree est rompu en quelque façon évidente. Mise à jour de votre question avec tous les messages d'erreur, backtraces, ou tout ce que vous pouvez faire pour nous aider à vous aider.

21voto

Steven Points 10243

Si je comprends votre question correctement:

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

ou si vous préférez (et si il y a une seule occurrence de l' timeSeries/values:

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

L' findall() méthode renvoie une liste de tous les éléments, tandis que l' find() retourne uniquement le premier élément correspondant. Le premier exemple passe en boucle sur tous les éléments trouvés, la deuxième passe en boucle sur les éléments enfants de l' values élément, dans ce cas, aboutissant au même résultat.

Je ne vois pas où le problème de ne pas trouver timeSeries vient de toutefois. Peut-être vous avez juste oublié le getroot() appel? (notez que vous n'avez pas vraiment besoin, car vous pouvez travailler à partir de la elementtree lui-même, si vous modifiez le chemin d'accès de l'expression, par exemple, /timeSeriesResponse/timeSeries/values ou //timeSeries/values)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X