Attributeerror: 'Nonetype' Object has no attribute 'text'

Asked

Viewed 974 times

-1

Hello I have a code that reads XML, but this XML may or may not have the field vICMSST and so I used a IF whether it is None, thus:

import xlrd
import xml.etree.ElementTree as ET
from itertools import chain
from copy import deepcopy
#Bibliotecas
#------------------------------------------------------------------------------------------#
    
tree = ET.parse(r"C:\Users\Expedição\Downloads\35200961974911000104550010000752631862357412-nfe (1).xml")
root = tree.getroot()
Contagem = 1
ns = {'nfe': 'http://www.portalfiscal.inf.br/nfe'}
print("#------------------------------------------------------------------------------------------------------#")
varialvel = input("coloque o valor da bonificação aqui: ")
for det in root.findall('.//nfe:det', ns):
    ICMS = det.find('.//nfe:vICMS', ns).text
    IPI = det.find('.//nfe:vIPI', ns).text
    quantidade = det.find('.//nfe:qCom', ns).text
    if det.find('.//nfe:vICMSST', ns).text is not None:
        ICMSST = det.find('.//nfe:vICMSST', ns).text
    else:
        ICMSST = 0

THE XML:

<nfeProc xmlns="http://www.portalfiscal.inf.br/nfe" versao="4.00">
<NFe xmlns="http://www.portalfiscal.inf.br/nfe">
<infNFe Id="NFe35200961974911000104550010000752631862357412" versao="4.00">
<ide>
...
</ide>
<emit>
...
</emit>
<dest>
...
</dest>
<det nItem="1">
<prod>
...
</prod>
<imposto>
<vTotTrib>3481.64</vTotTrib>
<ICMS>
<ICMS00>
<orig>0</orig>
<CST>00</CST>
<modBC>3</modBC>
<vBC>38857.60</vBC>
<pICMS>18.0000</pICMS>
<vICMS>6994.37</vICMS>
<vICMSST>884.54</vICMSST># CAMPO QUE PODE OU NÂO EXISTIR #
</ICMS00>
</ICMS>

But have obeyed this mistake:

AttributeError: 'NoneType' object has no attribute 'text'AttributeError: 'NoneType' object has no attribute 'text'

1 answer

2


Without more details, the problem seems to be in some of these lines:

ICMS = det.find('.//nfe:vICMS', ns).text
IPI = det.find('.//nfe:vIPI', ns).text
quantidade = det.find('.//nfe:qCom', ns).text
if det.find('.//nfe:vICMSST', ns).text

After all, you try to catch the text of a field without checking if it exists. If any of them do not exist, the return of find is None, and trying to catch the text of None, makes the mistake.

A suggestion is to create a generic function that gets the value of the field if it exists, and if it does not exist, returns some value default:

def get_text(node, nome, ns, valor_default=''):
    # procura pelo campo a partir do node
    campo = node.find(nome, ns)
    if campo is None: # campo não existe, retorna o valor default
        return valor_default
    return campo.text # retorna o text do campo

That is, it searches the field and returns the text. But if the field is not found, returns the value default (which by default is the empty string, but you can pass any other you want).

Then just do:

for det in root.findall('.//nfe:det', ns):
    ICMS = get_text(det, './/nfe:vICMS', ns)
    IPI = get_text(det, './/nfe:vIPI', ns)
    quantidade = get_text(det, './/nfe:qCom', ns)
    ICMSST = get_text(det, './/nfe:vICMSST', ns, 0) # se não encontrar, usar o zero como valor default

Browser other questions tagged

You are not signed in. Login or sign up in order to post.