Obtenir la valeur de L'élément avec minidom avec Python

Je crée une interface graphique pour L'API 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 nœud appelé "name":

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

Cela semble trouver le nœud, mais la sortie est ci-dessous:

[<DOM Element: name at 0x11e6d28>]

Comment pourrais-je l'obtenir pour imprimer la valeur du nœud?

95
demandé sur Martin Thoma 2008-11-25 16:57:02

8 réponses

Il devrait juste être

name[0].firstChild.nodeValue
133
répondu eduffy 2012-06-16 02:19:08

Probablement quelque chose comme ça si c'est la partie de 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é. Ainsi, vous voudrez passer en revue tous ses enfants et trouver tous les nœuds enfants qui sont des nœuds de texte. Un nœud peut avoir plusieurs nœuds de texte, par exemple.

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

Vous voulez à la fois 'blabla' et 'znylpx'; d'où le "".rejoindre(). Vous pouvez remplacer l'espace par un saut de ligne ou peut-être par rien.

55
répondu Henrik Gustafsson 2008-11-25 14:46:25

Vous pouvez utiliser quelque chose comme this.It travaillé 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
11
répondu samaksh 2011-02-20 20:30:33

Je sais que cette question est assez ancienne maintenant, mais je pensais que vous pourriez avoir un temps plus facile avec 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 super spécifique, mais je viens de le découvrir, et jusqu'à présent, il est beaucoup plus facile de me débrouiller que le minidom (puisque tant de nœuds sont essentiellement des espaces blancs).

Par exemple, vous avez le nom de la balise et le texte réel ensemble, comme vous vous y attendriez probablement:

>>> element[0]
<Element currentTime at 40984d0>
>>> element[0].tag
'currentTime'
>>> element[0].text
'2010-04-12 02:45:45'e
7
répondu LarrikJ 2013-04-25 07:42:31

La réponse ci-dessus est correcte, à savoir:

name[0].firstChild.nodeValue

Cependant pour moi, comme les autres, ma valeur était plus bas dans l'arbre:

name[0].firstChild.firstChild.nodeValue

Pour trouver cela, j'ai utilisé ce qui suit:

def scandown( elements, indent ):
    for el in elements:
        print("   " * indent + "nodeName: " + str(el.nodeName) )
        print("   " * indent + "nodeValue: " + str(el.nodeValue) )
        print("   " * indent + "childNodes: " + str(el.childNodes) )
        scandown(el.childNodes, indent + 1)

scandown( doc.getElementsByTagName('text'), 0 )

L'exécution de ceci pour mon simple fichier SVG créé avec Inkscape m'a donné:

nodeName: text
nodeValue: None
childNodes: [<DOM Element: tspan at 0x10392c6d0>]
   nodeName: tspan
   nodeValue: None
   childNodes: [<DOM Text node "'MY STRING'">]
      nodeName: #text
      nodeValue: MY STRING
      childNodes: ()
nodeName: text
nodeValue: None
childNodes: [<DOM Element: tspan at 0x10392c800>]
   nodeName: tspan
   nodeValue: None
   childNodes: [<DOM Text node "'MY WORDS'">]
      nodeName: #text
      nodeValue: MY WORDS
      childNodes: ()

J'ai utilisé xml.Dom.minidom, les différents champs sont expliqués sur cette page, MiniDom Python.

5
répondu LazyBrush 2016-07-20 12:15:18

J'ai eu un cas similaire, ce qui a fonctionné pour moi était:

Nom.firstChild.childNodes[0].données

XML est censé être simple et c'est vraiment le cas et je ne sais pas pourquoi le minidom de python l'a fait si compliqué... mais c'est comme ça que c'est fait

2
répondu robertzp 2011-10-06 03:10:30

Voici une réponse légèrement modifiée de Henrik pour plusieurs nœuds (ie. 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)
2
répondu khany 2011-10-24 18:51:35

La question a été répondue, ma contribution consiste à clarifier une chose qui peut dérouter les débutants:

Certaines des réponses suggérées et correctes ont utilisé {[0] } et d'autres ont utilisé firstChild.nodeValue à la place. Dans le cas où vous vous demandez quelle est la différence entre eux, vous devriez vous rappeler qu'ils font la même chose parce que nodeValue est juste un alias pour data.

La référence à ma déclaration peut être trouvée comme un commentaire sur le code source de minidom :

#nodeValue est un alias pour data

0
répondu Billal Begueradj 2018-04-18 08:52:08