JAXB gerando XML errado

4 respostas
javer

Tenho um objeto que quero passar para XML com o JAXB.

O xml correto seria algo como:
<?xml version="1.0" encoding="UTF-8" ?>
<CancNFe versao="2.00" xmlns="http://www.portalfiscal.inf.br/nfe">     
    <infCanc Id="ID35100902767116000186550010000266291010733080" >         
        <tpAmb>2</tpAmb>         
        <xServ>CANCELAR</xServ>         
        <chNFe>35100902767116000186550010000266291010733080</chNFe>         
        <nProt>784732847384</nProt>         
        <xJust>CLIENTE CANCELOU O SERVICO/COMPRA</xJust>     
    </infCanc>
</CancNFe>
Porém com o JAXB depois do marshal ele cria um XML assim:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:tCancNFe versao="2.00" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns="http://www.portalfiscal.inf.br/nfe">
    <infCanc Id="ID35100902767116000186550010000266291010733080">
        <tpAmb>2</tpAmb>
        <xServ>CANCELAR</xServ>
        <chNFe>35100902767116000186550010000266291010733080</chNFe>
        <nProt>784732847384</nProt>
        <xJust>CLIENTE CANCELOU O SERVIÇO/COMPRA</xJust>
    </infCanc>
</ns2:tCancNFe>
O que é esse ns2 que ele gera? Código:
emissor.bean.nfe.cancelamento.TCancNFe cancObj = new emissor.bean.nfe.cancelamento.TCancNFe();
emissor.bean.nfe.cancelamento.TCancNFe.InfCanc infCanc = new emissor.bean.nfe.cancelamento.TCancNFe.InfCanc();
infCanc.setChNFe(chaveAcesso);
infCanc.setNProt(protocolo);
infCanc.setTpAmb(Global.TIPO_AMBIENTE_NFe);
infCanc.setXServ("CANCELAR");
infCanc.setId("ID" + chaveAcesso);
infCanc.setXJust(justificativa);

cancObj.setInfCanc(infCanc);
cancObj.setVersao(NFe.VERSAO_LEIAUTE_NFE);

JAXBContext context = JAXBContext.newInstance(cancObj.getClass());
Marshaller marshaller = context.createMarshaller();

StringWriter sw = new StringWriter();
marshaller.marshal(cancObj, sw);

String xmlCancelamento = sw.toString();
Desse jeito nem dá para assinar. Como corrigir isso?

4 Respostas

PauloBrito

Eu também aguardo ansioso que alguém dê uma luz sobre isso. Pesquisei demais e não consegui encontrar uma solução.

Segue um POG que estou usando no momento:

private String ajustaNamespaces(String xml)  {
   return xml.replaceAll("xmlns:ns2=\".+#\"\\s", "");
}

Espero que ajude, pelo menos até encontrarmos uma solução decente…

A

Se vc já tem uma estrutura de objetos e somente quer criar seu XML, recomendo utilizar a API XStream, se não resolver seu problema tente outro.
XStream muito simples seu uso e fácil:
http://xstream.codehaus.org/

javer
Ok, bom o XStream, porém ele converte o XML "crú" e com a raíz com o nome inteiro do pacote, estranho, como faço para acertar? (ex: adic o xmlns) Como colocar os atributos? Ex: em infCanc tem id
emissor.bean.nfe.cancelamento.TCancNFe cancObj = new emissor.bean.nfe.cancelamento.TCancNFe();
        emissor.bean.nfe.cancelamento.TCancNFe.InfCanc infCanc = new emissor.bean.nfe.cancelamento.TCancNFe.InfCanc();
        infCanc.setChNFe(chaveAcesso);
        infCanc.setNProt(protocolo);
        infCanc.setTpAmb(Global.TIPO_AMBIENTE_NFe);
        infCanc.setXServ("CANCELAR");
        infCanc.setId("ID" + chaveAcesso);
        infCanc.setXJust(justificativa);
        cancObj.setInfCanc(infCanc);
        cancObj.setVersao(NFe.VERSAO_LEIAUTE_NFE);

        XStream xstream = new XStream();
        String xml = xstream.toXML(cancObj);
        System.out.println("XStream: \n"+xml);
        String xmlAssinado = assinarRaiz(xml);
<emissor.bean.nfe.cancelamento.TCancNFe>
  <infCanc>
    <tpAmb>2</tpAmb>
    <xServ>CANCELAR</xServ>
    <chNFe>35100902767116000186550010000266291010733080</chNFe>
    <nProt>784732847384</nProt>
    <xJust>CLIENTE CANCELOU O SERVICO/COMPRA</xJust>
    <id>ID35100902767116000186550010000266291010733080</id>
  </infCanc>
  <versao>2.00</versao>
</emissor.bean.nfe.cancelamento.TCancNFe>
Até agora não consegui encontrar uma forma de enviar um pedido de cancelamento de nota fiscal (com essas duas classes: NfeCancelamento2Stub e NfeCancelamento2CallbackHandler), se alguns do Srs. tiver um exemplo eu agradeço.
A

Bom configurar nomes, atributos, lists com o XStream é fácil: segue um exemplo

XStream xtream = new XStream(new DomDriver());		
xtream.useAttributeFor(SuaClasse.class, "atributoDaClasse"); //faz usar o atributo da classe como um atributo em seu XML
xtream.alias("NomeDeSuaPreferencia", SuaClasse.class); //faz ele trocar o nome, colocar um apelido para o nó do XML --resolve o problema do nome do pacote
xtream.addImplicitCollection(ClasseComCollection.class, "nomeAtributoComCollection"); //se vc tiver uma collection em seu objeto e quiser formatar isso de uma melhor forma utilize este metodo

Espero que te ajude, mais informações vc vai pegar no site está tudo bem explicado na documentação
Até mais

Criado 24 de setembro de 2010
Ultima resposta 25 de set. de 2010
Respostas 4
Participantes 3