120 votes

Obtenir la valeur d'un élément avec minidom avec Python

Je suis en train de créer une interface graphique pour l'API de Eve Online en Python.

J'ai réussi à extraire les données XML de leur serveur.

J'essaie de récupérer la valeur d'un noeud appelé "nom" :

from xml.dom.minidom import parse
dom = parse("C:\\eve.xml")
name = dom.getElementsByTagName('name')
print name

Cela semble trouver le noeud, mais la sortie est ci-dessous :

[<DOM Element: name at 0x11e6d28>]

Comment faire pour qu'il imprime la valeur du nœud ?

7 votes

Il semble que la réponse à la plupart des questions sur le "minidom" soit "utilisez ElementTree".

0 votes

En revanche, si vous apprenez minidom au lieu d'ElementTree, vous mettrez peut-être un peu plus de temps à démarrer, mais vous serez ensuite capable de faire exactement la même chose dans pratiquement n'importe quel autre langage de programmation que vous connaissez ou que vous finirez par apprendre, et vous pourrez également tirer parti de nombreux autres outils. Vous payez votre argent et vous faites votre choix.

180voto

eduffy Points 17061

Il devrait juste être

name[0].firstChild.nodeValue

5 votes

Quand je fais name[0].nodeValue, il me renvoie "None", juste pour tester, je lui ai passé name[0].nodeName et il m'a donné "name", ce qui est correct. Avez-vous une idée ?

28 votes

Qu'en est-il de name[0].firstChild.nodeValue ?

7 votes

Veillez simplement à ne pas vous fier aux détails de mise en œuvre du générateur xml. Il n'y a aucune garantie que le premier enfant soit le site ni le nœud de texte sólo dans tous les cas où il peut y avoir plus d'un noeud enfant.

60voto

Henrik Gustafsson Points 11755

Probablement quelque chose comme ça si c'est la partie texte que vous voulez...

from xml.dom.minidom import parse
dom = parse("C:\\eve.xml")
name = dom.getElementsByTagName('name')

print " ".join(t.nodeValue for t in name[0].childNodes if t.nodeType == t.TEXT_NODE)

La partie texte d'un nœud est considérée comme un nœud en soi, placé comme un nœud enfant de celui que vous avez demandé. Vous devrez donc passer en revue tous ses enfants et trouver tous les nœuds enfants qui sont des nœuds de texte. Un noeud peut avoir plusieurs noeuds de texte ; par exemple, un noeud de texte peut avoir plusieurs noeuds de texte.

<name>
  blabla
  <somestuff>asdf</somestuff>
  znylpx
</name>

Vous voulez à la fois 'blabla' et 'znylpx', d'où le " ".join(). Vous pouvez remplacer l'espace par un saut de ligne, ou par rien.

12voto

samaksh Points 101

Vous pouvez utiliser quelque chose comme ça. Ça a marché pour moi.

doc = parse('C:\\eve.xml')
my_node_list = doc.getElementsByTagName("name")
my_n_node = my_node_list[0]
my_child = my_n_node.firstChild
my_text = my_child.data 
print my_text

9voto

LarrikJ Points 437

Je sais que cette question est assez vieille maintenant, mais j'ai pensé que vous auriez plus de facilité à ElementTree

from xml.etree import ElementTree as ET
import datetime

f = ET.XML(data)

for element in f:
    if element.tag == "currentTime":
        # Handle time data was pulled
        currentTime = datetime.datetime.strptime(element.text, "%Y-%m-%d %H:%M:%S")
    if element.tag == "cachedUntil":
        # Handle time until next allowed update
        cachedUntil = datetime.datetime.strptime(element.text, "%Y-%m-%d %H:%M:%S")
    if element.tag == "result":
        # Process list of skills
        pass

Je sais que ce n'est pas très précis, mais je viens de le découvrir, et jusqu'à présent, il est beaucoup plus facile de s'y retrouver que dans le minidom (puisque de nombreux nœuds sont essentiellement des espaces blancs).

Par exemple, le nom de la balise et le texte proprement dit sont réunis, comme on peut s'y attendre :

>>> element[0]
<Element currentTime at 40984d0>
>>> element[0].tag
'currentTime'
>>> element[0].text
'2010-04-12 02:45:45'e

3voto

khany Points 558

Voici une réponse légèrement modifiée de celle d'Henrik pour les nœuds multiples (c'est-à-dire lorsque getElementsByTagName renvoie plus d'une instance)

images = xml.getElementsByTagName("imageUrl")
for i in images:
    print " ".join(t.nodeValue for t in i.childNodes if t.nodeType == t.TEXT_NODE)

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