Topic: 'NoneType' object has no attribute 'text'  (Letto 53 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline RMoggia

  • python unicellularis
  • *
  • Post: 1
  • Punti reputazione: 0
    • Mostra profilo
'NoneType' object has no attribute 'text'
« il: Gennaio 07, 2021, 12:23 »
Buongiorno.
Ho scritto questo codice con l'intenzione di estrarre uno o più valori da un file xml.
import xml.etree.ElementTree as ET
"""
foo
"""
def foo(valueName):
    tree = ET.parse('Config.xml')
    root = tree.getroot()
    nomv = './/'+valueName
    return root.find(nomv).text

print(foo("value"))

Ma ottengo l'errore in oggetto.
Io non sono un esperto di python, sono all'inizio, qualcuno può aiutarmi?
Grazie in anticipo

Offline nuzzopippo

  • python neanderthalensis
  • ****
  • Post: 336
  • Punti reputazione: 0
    • Mostra profilo
Re:'NoneType' object has no attribute 'text'
« Risposta #1 il: Gennaio 07, 2021, 16:26 »
Guarda, non conosco la libreria XML, sin ora non l'ho mai usata, prendimi con le molle, ma ho dato una guardata alla docs, e visto l'esempio per lo XPath, la funzione "sarebbe" corretta SE il nodo cercato esiste ... il problema viene se il nodo cercato NON esiste, esempio, posto un file "nomi.xml" con questo contenuto :
<?xml version="1.0" encoding="UTF-8"?>
<utenti>
    <utente anni="20">
        <nome>Ema</nome>
        <cognome>Princi</cognome>
        <indirizzo>Torino</indirizzo>
    </utente>
    <utente anni="54">
        <nome>Max</nome>
        <cognome>Rossi</cognome>
        <indirizzo>Roma</indirizzo>
    </utente>
</utenti>


Il Tuo codice risponderà bene cercando un nodo esistente, p.e. "cognome", ma darà errore cercando un tag inesistente, p.e. "lavoro", vedi giù
>>> def foo(value_name):
tree = ET.parse('nomi.xml')
root = tree.getroot()
nomv = './/' + value_name
return root.find(nomv).text

>>> print(foo('cognome'))
Princi
>>> foo('lavoro')
Traceback (most recent call last):
  File "<pyshell#64>", line 1, in <module>
    foo('lavoro')
  File "<pyshell#63>", line 5, in foo
    return root.find(nomv).text
AttributeError: 'NoneType' object has no attribute 'text'
>>>

al problema si può ovviare eseguendo una verifica preliminare assegnando il risultato ad una variabile e se questa risulta vera restituire il testo, qualcos'altro altrimenti, ovviamente bisogna prevenire un eventuale errore, p.e. così
>>> def foo(value_name):
tree = ET.parse('nomi.xml')
root = tree.getroot()
nomv = './/' + value_name
try:
cognome = root.find(nomv).text
return cognome
except AttributeError:
pass


>>> print(foo('cognome'))
Princi
>>> print(foo('lavoro'))
None
>>>


... per altro, la Tua routine si ferma sempre e comunque alla prima evenienza trovata, per averle tutte bisognerebbe utilizzare "findall()"
>>> def foo(value_name):
tree = ET.parse('nomi.xml')
root = tree.getroot()
nomv = './/' + value_name
result = []
for e in root.findall(nomv):
result.append(e.text)
return result

>>> foo('cognome')
['Princi', 'Rossi']


per ulteriori domande, la documentazione Ti riponderà meglio di me ;)