Return a specific XML field

Asked

Viewed 97 times

1

I am creating a program that aims to obtain data from an XML, I am using xml.etree.ElementTree for this, but I’m not able to create a for to call the tags cEAN and qCom.

The XML used:

<nfeProc xmlns="http://www.portalfiscal.inf.br/nfe" versao="4.00">
<NFe xmlns="http://www.portalfiscal.inf.br/nfe">
<infNFe versao="4.00" Id="NFe35200823520039000135550010000031451090031450">
<ide>
...
</ide>
<emit>
...
</emit>
<dest>
...
</dest>
<det nItem="1">
<prod>
<cProd>01.304</cProd>
<cEAN>7898338312758</cEAN>
<xProd>AF QUADRIAXIAL 6 QR6 HURRICANE</xProd>
<NCM>85182100</NCM>
<CEST>0105700</CEST>
<CFOP>5405</CFOP>
<uCom>par</uCom>
<qCom>60.0000</qCom>
<vUnCom>53.6000000000</vUnCom>
<vProd>3216.00</vProd>
<cEANTrib>7898338312758</cEANTrib>
<uTrib>par</uTrib>
<qTrib>60.0000</qTrib>
<vUnTrib>53.6000000000</vUnTrib>
<indTot>1</indTot>
</prod>
<imposto>
...
</imposto>
<infAdProd>7898338312758</infAdProd>
</det>

What I’ve tried to do:

import xml.etree.ElementTree as ET
tree = ET.parse("C:\\Users\\Expedição\\Videos\\XML\\xml_teste1.xml")
root = tree.getroot()

for det in root.findall('det'):
  quantidade = det.find('qCom').text
  EAN = det.find('cEAN').text
  print (quantidade,EAN)

1 answer

0


They are basically two problems:

  • According to the documentation, findall search for the elements that are direct children of the element in question. Like the tag det is inside infNFe, which in turn is within NFe, it is not found. But this can be fixed using Xpath (in case, it would be .//nome_da_tag).
  • The namespace http://www.portalfiscal.inf.br/nfe is also part of the tag name, and should be used in the search string.

Then it would be:

for det in root.findall('.//{http://www.portalfiscal.inf.br/nfe}det'):
    quantidade = det.find('.//{http://www.portalfiscal.inf.br/nfe}qCom').text
    EAN = det.find('.//{http://www.portalfiscal.inf.br/nfe}cEAN').text
    print(quantidade, EAN)

But typing the namespace for all tags can be a bit boring, so you can create a dictionary that maps this namespace to a shorter name:

ns = {'nfe': 'http://www.portalfiscal.inf.br/nfe'}
for det in root.findall('.//nfe:det', ns):
    quantidade = det.find('.//nfe:qCom', ns).text
    EAN = det.find('.//nfe:cEAN', ns).text
    print(quantidade, EAN)

Thus, the dictionary maps the namespace http://www.portalfiscal.inf.br/nfe for the key nfe, and in the search strings just put nfe:nome_da_tag.

  • Thank you very much, clarified the concept of hierarchy,vlw

  • can I take a doubt? this way written up you call all cEAN more it is possible to call only a specific product.

  • @Valterferreira I don’t know if I understand, but if you only want a product, you can search for its tag, see its value and only get his cEAN (if nome_produto == 'bla': busca o cEAN, or something like that). Once you know how to search for any tag, you can make the logic you want. If it’s not that, maybe it’s worth it ask another question

Browser other questions tagged

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