web-dev-qa-db-fra.com

Lecture de XML à l'aide de Python minidom et itération sur chaque nœud

J'ai une structure XML qui ressemble à ceci, mais à une échelle beaucoup plus grande:

<root>
    <conference name='1'>
        <author>
            Bob
        </author>
        <author>
            Nigel
        </author>
    </conference>
    <conference name='2'>
        <author>
            Alice
        </author>
        <author>
            Mary
        </author>
    </conference>
</root>

Pour cela, j'ai utilisé le code suivant:

dom = parse(filepath)
conference=dom.getElementsByTagName('conference')
for node in conference:
    conf_name=node.getAttribute('name')
    print conf_name
    alist=node.getElementsByTagName('author')
    for a in alist:
        authortext= a.nodeValue
        print authortext

Cependant, le texte automatique imprimé est "Aucun". J'ai essayé de jouer avec des variantes comme celles ci-dessous, mais cela provoque la rupture de mon programme.

authortext=a[0].nodeValue

La sortie correcte doit être:

1
Bob
Nigel
2
Alice
Mary

Mais ce que je reçois c'est:

1
None
None
2
None
None

Avez-vous des suggestions sur la façon de résoudre ce problème?

24
GobiasKoffi

votre authortext est de type 1 (ELEMENT_NODE), vous devez normalement avoir TEXT_NODE pour obtenir une chaîne. Cela fonctionnera

a.childNodes[0].nodeValue
24
SilentGhost

Les nœuds d'élément n'ont pas de nodeValue. Vous devez regarder les nœuds de texte à l'intérieur d'eux. Si vous savez qu'il y a toujours un nœud de texte à l'intérieur, vous pouvez dire element.firstChild.data (les données sont identiques à nodeValue pour les nœuds de texte).

Attention: s'il n'y a pas de contenu texte, il n'y aura pas de nœuds texte enfant et element.firstChild sera nul, provoquant le .data l'accès échoue.

Un moyen rapide d'obtenir le contenu des nœuds de texte enfant directs:

text= ''.join(child.data for child in element.childNodes if child.nodeType==child.TEXT_NODE)

Dans DOM Level 3 Core, vous obtenez la propriété textContent que vous pouvez utiliser pour obtenir du texte de l'intérieur d'un élément de manière récursive, mais minidom ne le prend pas en charge (certaines autres implémentations DOM Python font ).

6
bobince

Accès rapide:

node.getElementsByTagName('author')[0].childNodes[0].nodeValue
2
Priyabrata

Puisque vous avez toujours une valeur de données de texte par auteur, vous pouvez utiliser element.firstChild.data

dom = parseString(document)
conferences = dom.getElementsByTagName("conference")

# Each conference here is a node
for conference in conferences:
    conference_name = conference.getAttribute("name")
    print 
    print conference_name.upper() + " - "

    authors = conference.getElementsByTagName("author")
    for author in authors:
        print "  ", author.firstChild.data
    # for

    print
1
Swadhikar C

J'ai joué un peu avec, et voici ce que j'ai pu faire:

# ...
authortext= a.childNodes[0].nodeValue
print authortext

conduisant à la sortie de:

 C:\temp\py> xml2.py 
 1 
 Bob 
 Nigel 
 2 
 Alice 
 Alice Marie

Je ne peux pas vous dire exactement pourquoi vous devez accéder à childNode pour obtenir le texte interne, mais au moins c'est ce que vous cherchiez.

0
Mark Rushakoff