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?
8 réponses
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.
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
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
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.
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
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)
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 pourdata