Leitura de XML de NFe com JDOM

Pessoal estava com um problema para ler um xml de uma NFe, o problema era por causa do NameSpace, o famoso atributo xmlns, depois de ralar bastante consegui ler o bendito arquivo com sucesso utilizando o JDOM. Segue o código:

package arquivos;

import java.io.File;
import javax.swing.JOptionPane;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

/*

  • Desenvolvido por Fabiano Costa de Alvarenga.
  • Esta classe recupera dados de um XML de NF-e.

*/
public class LeitorXML {

private SAXBuilder sb;
private Document d;

public LeitorXML(String arquivo) {
	// TODO Auto-generated constructor stub
	try {
		sb = new SAXBuilder();
		d = sb.build(new File(arquivo));
	} catch (Exception e) {
		// TODO: handle exception
		JOptionPane.showMessageDialog(null, "Exceção ao processar arquivo! "+e.getMessage());
	}
}

public String getEmailNFe() {
	try {

                                         [color=blue]// AQUI ESTÁ O MAIOR SEGREDO 
		XPath xPath = XPath.newInstance("//k:nfeProc/k:NFe/k:infNFe/k:dest/k:email"); 
		xPath.addNamespace("k", d.getRootElement().getNamespaceURI()); 

                                            Element node = (Element) xPath.selectSingleNode(d.getRootElement()); 
                                            return node.getText();[/color]

	} catch (Exception e) {
		JOptionPane.showMessageDialog(null, "Erro ao processar arquivo! "+e.getMessage());
		return null;
	}
}

public static void main(String[] args) {

	LeitorXML buscarDadosEmXML = new LeitorXML("procNfe2.xml");
	System.out.println("E-mail Destinatário: "+buscarDadosEmXML.getEmailNFe());

}

}

Dúvidas: fabiano.costa.alvarenga@gmail.com

1 curtida

o que significa o k que vc botou dentro das consultas dos dados no XPath?
Eu fiz aqui o mesmo esquema pra ler XML de NFe mas eu fiz com XPath normal, só indicando a tag que eu queria localizar, por ex: [color=orange]"//det[1]//vProd"[/color]

Amigão, não sei se o XML da NFe que você consegue ler tem o atributo nameSpace chamado xmlns. Por não se tratar de um nameSpace default é necessário setarmos o nameSpace igual ao do XML, daí lemos o atributo xmlns e setamos ele no nosso XPath através do prefixo do nameSpace, que neste caso é a letra “K”, vale lembrar que poderia ser qualquer outra letra.

Bom dia!

Antes de mais nada gostaria de agradecer a sua atitude de compartilhar conhecimento, me ajudou muito.

Estou desenvolvendo uma ferramenta aqui para importar algumas informações da NFe para o sistema da empresa que trabalho. Gostaria de saber se você poderia indicar como pegar os itens da NFe.

Obrigado.

enlatados

Usa p XStream pra transformar os Xmls em Objetos java.

Boa tarde meus caros amigos, Jonathan, Enlatados e os demais.

Não é tão simples transformar um xml em objetos quando se tem atributo xmlns (nameSpace), pois eu tive muitas dificuldades. Daí achei importante contribuir com este post.

Enlatados, em primeiro lugar é necessário conhecer a estrutura do xml da nf-e, este será seu único desafio, pois basta usar o trecho de código que postei acima mudando apenas o caminho do elemento qua deseja recuperar para o seu sistema.

// AQUI ESTÁ O MAIOR SEGREDO
//XPath xPath = XPath.newInstance("//k:nfeProc/k:NFe/k:infNFe/k:dest/k:email"); // ler email do destinatário no xml da nf-e
//XPath xPath = XPath.newInstance("//k:nfeProc/k:NFe/k:infNFe/k:dest/k:xNome"); // ler nome do destinatário no xml da nf-e
//XPath xPath = XPath.newInstance("//k:nfeProc/k:NFe/k:infNFe/k:dest/k:CNPJ"); // ler cnpj do destinatário no xml da nf-e
xPath.addNamespace(“k”, d.getRootElement().getNamespaceURI());

Element node = (Element) xPath.selectSingleNode(d.getRootElement());
return node.getText();

Não é difícil, basta conhecer o caminho xml para acessar os dados de cada elemento do arquivo. Se precisar posso lhe mandar o schema xml da nf-e ou você pode pegá-lo no portal nacional da nf-e.

http://www.nfe.fazenda.gov.br/portal/listaSubMenu.aspx?Id=tW+YMyk/50s

Clique no menu documentos e veja manual de integração do contribuinte.

Um grande abraço, caso necessite de mais uma ajuda estarei a disposição.

Bom dia Fabiano!

Preciso de sua ajuda.

Segui seus posts e tenho conseguido destrinchar os arquivos XML da NFe… com excessão do nó

Quando faço os seguintes comandos:

XPath xPath = XPath.newInstance(raiz0 + raizNfe + raizSignature ); // fixei os caminhos com Strings
xPath.addNamespace(“k”, d.getRootElement().getNamespaceURI());
Element node = (Element) xPath.selectSingleNode(d.getRootElement());
List lista = node.getChildren();

Acontece o seguinte erro:

“Erro ao processar o arquivo: Null”

quando comento a linha:
// Element node = (Element) xPath.selectSingleNode(d.getRootElement());

não ocorre mais o erro. Mas claro que então não consigo trabalhar aquele nó…

Onde estou errando?

Obrigado desde já pela atenção.

Parabéns!

Gostei muito fiz e está funcionando mas estou com uma dúvida.
Como faço o loop dos itens da NFe?
Desculpem minha ignorância.
Mas só estou conseguindo fazer listar o primeiro item da lista.

Grato pela ajuda.

mesma dúvida do Siqi…
como listar todos os produtos da nota?

Olá pessoal…

bom, vendo o assunto tratado neste post vou deixar minha colaboração…

para trabalhar com a NF-e aqui na empresa utilizo o xerces que nos atende muito bem com essas manipulações…

para ler uma NF-e eu utilizo o código abaixo:

[code]
public A lerNFe(){

    try {
        
        A infNFe = new A();
        File arq = new File(caminhoXml);

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(arq);
        Element elem = doc.getDocumentElement();
        Node noNFe = elem.getElementsByTagName("infNFe").item(0);

        JAXBContext context = JAXBContext.newInstance(infNFe.getClass());
        Unmarshaller um = context.createUnmarshaller();
        infNFe = (A)um.unmarshal(noNFe);
        
        return infNFe;
        
    } catch (ParserConfigurationException ex) {
        ex.printStackTrace();
        return null;
    } catch (SAXException ex) {
        ex.printStackTrace();
        return null;
    } catch (IOException ex) {
        ex.printStackTrace();
        return null;
    } catch (JAXBException ex) {
        ex.printStackTrace();
        return null;
    }
    
}[/code]

para o mesmo funcionar vcs tem que ter um objeto A (infNfe) como no manual da NF-e …
ai é so converter o xml nesse objeto que então vcs podem tirar várias informações dele.

Até

Minha dica que dou é a seguinte. Quando comecei escrever um código para gerar nf-e, utilizei o XStream.

Como é uma aplicação particular e estava fazendo em desktop, acabei desistindo para fazer em web.

Mas, nessa parte da nf-e eu fui lendo o manual, e de acordo com as especificações dele, fui gerando todos os beans. Depois de ter todos os beans gerados, fica mais fácil trabalhar.

Vou verificar se ainda tenho os beans e coloco aqui pra voces.

Olá, pessoal!

Deixo aqui a minha solução para a leitura de arquivo XML da NFe:

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

/**
*

  • @author Adelcio C. Porto

  • email: portoinfo@sercomtel.com.br
    */
    public class LerArqXML {

    private void lerarq() {
    //Aqui você informa o nome do arquivo XML.
    File f = new File(“C://arquivo.XML”);

//Criamos uma classe SAXBuilder que vai processar o XML
SAXBuilder sb = new SAXBuilder();

//Este documento agora possui toda a estrutura do arquivo.
Document d;
try {
d = sb.build(f);
//Recuperamos o elemento root
Element nfe = d.getRootElement();

//Recuperamos os atributos filhos (Attributes)
List atributes = nfe.getAttributes();
Iterator i_atr = atributes.iterator();

//Iteramos com os atributos filhos
while (i_atr.hasNext()) {
Attribute atrib = (Attribute) i_atr.next();
System.out.println("\nattribute de ("+nfe.getName()+"):"+ atrib.getName()+" - valor: "+atrib.getValue());
}
//Recuperamos os elementos filhos (children)
List elements = nfe.getChildren();
Iterator i = elements.iterator();

//Iteramos com os elementos filhos, e filhos do dos filhos
while (i.hasNext()) {
Element element = (Element) i.next();
System.out.println(“element:”+ element.getName());
trataElement(element);
}

    } catch (JDOMException ex) {
        Logger.getLogger(LerArqXML.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(LerArqXML.class.getName()).log(Level.SEVERE, null, ex);
    }


}

private void trataElement(Element element) {

//Recuperamos os atributos filhos (Attributes)
List atributes = element.getAttributes();
Iterator i_atr = atributes.iterator();

//Iteramos com os atributos filhos
while (i_atr.hasNext()) {
Attribute atrib = (Attribute) i_atr.next();
System.out.println("\nattribute de ("+element.getName()+"):"+ atrib.getName()+" - valor: "+atrib.getValue());
}
//Recuperamos os elementos filhos (children)
List elements = element.getChildren();
Iterator it = elements.iterator();

    //Iteramos com os elementos filhos, e filhos do dos filhos
    while (it.hasNext()) {
        Element el = (Element) it.next();
        System.out.println("element("+element.getName()+"):"+ el.getName()+" - Valor: "+el.getText());

        //  aqui voce pode escolher qual(is) campo(s) quer manipular
        if (el.getName().equals("nNF")) {
            //  grava_no_banco de dados(element.getAttributeValue("nNF"));
            System.out.println("encontrou nNF . . . com valor: "+el.getText());
        }
        trataElement(el);
    }
}
public static void main (String[] args) {
    LerArqXML lexml = new LerArqXML();
    lexml.lerarq();
}

}

1 curtida

Boa noite pessoal, segue exemplo de leitura de NFe.

1 - Download dos esquemas XML da NFe 3.10 do site da RFB (http://www.nfe.fazenda.gov.br/portal/listaConteudo.aspx?tipoConteudo=/fwLvLUSmU8=);

2 - Descompacte o arquivo ZIP dentro de uma pasta e execute via prompt de comando o seguinte comando (xjc nfe_v3.10.xsd -p br.com.nfe.entity);

3 - Copie todos os arquivos gerados pelo passo 2 para dentro do seu projeto. (no meu caso crie uma pasta br.com.nfe.entity)

4 - Insira a Annotation (@XmlRootElement(name=“nfeProc”)) sobre a classe TNfeProc.java que foi gerada pelo passo 2;

5 - implemente esta classe abaixo:

package br.com.nfe;

import br.com.nfe.entity.TNFe;
import br.com.nfe.entity.TNfeProc;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;

/**

  • Created by Alvarenga Fabiano on 12/05/2015.
    */
    public class NFeXmlHelp {

    public static void main(String [] args){

     // Caminho do arquivo XML da NFe
     String xmlFilePathNFe3 = "src//33150400106206000109550000000221031470060710-procNfe.xml";
     JAXBContext context = null;
     TNfeProc tNfeProc = null;
    
     try {
    
         // Realizando o parser do XML da NFe para Objeto Java
         context = JAXBContext.newInstance(TNfeProc.class.getPackage().getName());
         Unmarshaller unmarshaller1 = context.createUnmarshaller();
    
         // Este é o seu Objeto Java da NFe (tNfeProc)
         tNfeProc = (TNfeProc) unmarshaller1.unmarshal(new File(xmlFilePathNFe3));
    
         // Iterando na lista de produtos da NFe
         for (TNFe.InfNFe.Det item : tNfeProc.getNFe().getInfNFe().getDet())
             System.out.println(
                     "Item: "+item.getNItem()+
                             " Codigo: "+item.getProd().getCProd()+
                             " Descricao: "+item.getProd().getXProd()+
                             " Valor: "+item.getProd().getVProd()
             );
    
     } catch (JAXBException e) {
         e.printStackTrace();
     }
    

    }

}

-------- FIM ------------

Pessoal espero ter ajudado…

1 curtida

Boa tarde

Consegui o acesso a NFe, mas não consigo acessar os campos de imposto por item, alguma sugestão?

Consegui o acesso a NFe, mas não consigo acessar os campos de imposto por item, alguma sugestão?

Obrigado Fabiano, e muito obrigado portoinfo2 estou utilizando aqui o seu código e deu certo! Muito obrigado mesmo pela contribuição de vocês!

portoinfo2, só não sei como colocar esses dados em um arrayList, todo jeito que eu faço não dá certo. Estou utilizando em uma aplicação web com primefaces fileupload, para subir o arquivo e ler no console está funcionando perfeitamente. Colocar os dados em objeto não está tendo problemas mas colocar esse objeto em arrayList não dá certo ele me retorna um erro tipo que não pode ter Array.add(objeto) dentro do método. Sou iniciante em programação e ainda não entendo bem como funciona.

Muito obrigado por ler.

B. tarde quando eu tento colocar esse opção de cima, me mostra a seguinte mensagem classe ou interface enum expected.

Muito obrigado pela colaboração Fabiano, muito útil