Lentidão ao validar XML NFe

Estou tentando validar XML NFe e encontrando muitos problemas. Procurei algum tópico aqui no fórum mas não encontrei nada que ajudasse.
Estou procurando uma forma de validar XML da receita da maneira mais rápida possível. Não preciso saber aonde está o erro e sim, se o XML é válido ou não rápidamente.

Até agora tentei duas formas de validação. Usando xsd e jaxb + xsd e dois demoram em torno de 30s para fazer a validação. Se alguém puder me dar alguma dica, eu vou ficar muito agradecido.

import java.io.BufferedReader;  
import java.io.FileInputStream;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.io.StringReader;  
import java.net.URL;  
  
import javax.xml.parsers.DocumentBuilder;  
import javax.xml.parsers.DocumentBuilderFactory;  
import javax.xml.transform.stream.StreamSource;  
import javax.xml.validation.Schema;  
import javax.xml.validation.SchemaFactory;  
import javax.xml.validation.Validator;  
  
import org.xml.sax.InputSource;  
import org.xml.sax.SAXParseException;  
  
public class NFeValidacaoXML {  
  
    public static String ValidaDoc(String stringXml, String xsdFileName) {  
        //Define o tipo de  - we use W3C    
        String schemaLang = "http://www.w3.org/2001/XMLSchema";  
        //valida driver    
        SchemaFactory factory = SchemaFactory.newInstance(schemaLang);  
        //    
        try {  
            URL xsdPath = NFeValidacaoXML.class.getResource("/schemas/" + xsdFileName);  
//            URL xsdPath = new URL("C:/Users/andre/Desktop/schemas/" + xsdFileName);    
  
            Schema schema = factory.newSchema(new StreamSource(xsdPath.toURI().toString()));  
            Validator validator = schema.newValidator();  
            //Perform the validation:    
            validator.validate(new StreamSource(new StringReader(stringXml)));  
            DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();  
            DocumentBuilder builder = fact.newDocumentBuilder();  
            builder.parse(new InputSource(new StringReader(stringXml)));  
        } catch (Exception e) {  
            if (e instanceof SAXParseException) {  
                return "XML Parse Error on Col: " + ((SAXParseException) e).getColumnNumber() + " | Lin: " + ((SAXParseException) e).getLineNumber() + " - " + ((SAXParseException) e).getLocalizedMessage();  
            } else {  
                return "Unknow error attemping to validate XML.";  
            }  
        }  
        return "";  
    }  
  
    public static String validaPedCartaCorrecao(String stringXml) {  
        return ValidaDoc(stringXml, "envCCe_v1.00.xsd");  
    }  
  
    public static String validaRetCartaCorrecao(String stringXml) {  
        return ValidaDoc(stringXml, "retEnvCCe_v1.00.xsd");  
    }  
  
    public static String validaNota(String stringXml) throws Exception {  
        return ValidaDoc(stringXml, "procNFe_v3.10.xsd");  
    }  
  
    //parametro caminho do xml    
    private static String lerXML(String fileXML) throws IOException {  
        String linha = "";  
        StringBuilder xml = new StringBuilder();  
  
        BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(fileXML)));  
        while ((linha = in.readLine()) != null) {  
            xml.append(linha);  
        }  
        in.close();  
  
        return xml.toString();  
    }  
  
    public static void main(String[] args) {  
        try {  
//            String xml = lerXML("C:/Users/andre/Desktop/42161175374736000129550020000334281000007234-nfe.xml");  
            String xml = lerXML("C:/Users/andre/Desktop/xmlNfe.xml");  
            String deuCerto = NFeValidacaoXML.validaNota(xml);  
            if (!deuCerto.isEmpty()) {  
                System.out.println("************ ERRO *********************** : " + deuCerto);  
            } else {  
                System.out.println("************ DEU CERTO *********************** ");  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  


Usando jaxb:


public class Validator {  
  
    /** 
     * Realiza a validacao do objeto com o arquivo XSD. 
     * 
     * @param xsdFile nome do arquivo XSD. 
     * @param object objeto a ser validado. 
     */  
    public static void validator(String xsdFile, Object object) {  
        try {  
  
            JAXBContext jc = JAXBContext.newInstance(object.getClass());  
            JAXBSource source = new JAXBSource(jc, object);  
  
            SchemaFactory sf = SchemaFactory.newInstance(  
                    XMLConstants.W3C_XML_SCHEMA_NS_URI  
            );  
            Schema schema = sf.newSchema(new File(xsdFile));  
  
            javax.xml.validation.Validator validator = schema.newValidator();  
            validator.setErrorHandler(new ValidatorErrorHandler());  
            validator.validate(source);  
  
            System.out.println("Successful validation!");  
        } catch (SAXException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (JAXBException e) {  
            e.printStackTrace();  
        }  
    }  
  
    /** 
     * Realiza a conversao (unmarshal) de um arquivo XML em um objeto do seu 
     * tipo. 
     * 
     * @param clazz classe referente ao objeto a ser criado a partir do XML. 
     * @param fileXml nome do arquivo XML a ser convertido em objeto. 
     * @return novo objeto. 
     * @throws java.io.FileNotFoundException 
     */  
    public static Object unmarshalFromFile(Class clazz, String fileXml) throws FileNotFoundException {  
        JAXBContext context = null;  
        try {  
            context = JAXBContext.newInstance(clazz);  
            Unmarshaller unmarshaller = context.createUnmarshaller();  
            return unmarshaller.unmarshal(  
                    new FileInputStream(fileXml)  
            );  
        } catch (JAXBException e) {  
            e.printStackTrace();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        }  
        return null;  
    }  
  
    public static void main(String[] args) {          
        try {  
            TNfeProc teste = (TNfeProc) unmarshalFromFile(TNfeProc.class, "C:/Users/andre/Desktop/42161175374736000129550020000334281000007234-nfe.xml");  
            validator("C:/Users/andre/Desktop/schemas/procNFe_v3.10.xsd", teste);  
        } catch (FileNotFoundException ex) {  
            ex.printStackTrace();  
        }  
          
    }  
}

Boa tarde!

Nos arquivos XSD que você está utilizando pra validar, procure se existe algum parâmetro tipo maxOccurs="5000", se tiver alguma com um valor muito alto assim, teste reduzir o valor, pra maxOccurs="100" por exemplo. Faça um backup dos seus XSD.

Eu lembro que uma vez estava ocorrendo essa lentidão comigo, e no fim era a Tag Vol que demorava pra validar devido a esse maxOccurs="5000".

OBS: Eu sempre envio uma NF-e por vez, e geralmente o volume informado pelos meus clientes não são valores tão altos, em caso de envio de várias NF-e em um lote este valor pode ser insuficiente pra você, mas não custa tentar pra ajustar a sua necessidade.

Espero que resolva.

1 curtida

Funcionou Bruno!!!

Ficou muito mais rápido, caiu de 30s para 2s.

Obrigado pela ajuda!

Imagina!

Mas como eu disse, verifique se você realmente não vai precisar de toda essa precisão que você reduziu, senão pode dar problemas.