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();
}
}
}