Montando Arquivo XML x NF-e

Para quem deseja começar a preparar o sistema da NF-e (Nota Fiscal Eletrônica), aqui vai uma dica muito interessante: como montar parte da estrutura XML
.

É importante lembrar que, a NF-e utiliza muito mais que isso. Não é só a estruturação do arquivo XML que é necessário, mas sim todo processo de validação dos dados, assinatura do arquivo, certificado etc.

Mas aqui falaremos apenas sobre a estrutura inicial do XML.
Neste exemplo a seguir será mostrado como: adicionar um nó; e como adicionar um nó como filho de outro nó.

Breve explicação do que será feito:
>> Vamos declarar uma variável do tipo IXmlNode, ela será chamada de "Root", e será usada por vários procedimentos.

>> Criaremos três procedimentos: CabecalhoXML; Informacao1 e Informacao2.
No CabecalhoXML é onde será criado todo o cabeçalho do arquivo XML.
Em Informacao1 e Informacao2, é onde irá conter os dados que irá compor o arquivo.

>> Criaremos uma função: CriaDirCaminho(const NomeSubDir: string): boolean;
Essa função é para criar uma pasta (no nosso exemplo, será a pasta "TESTE") em um diretório qualquer informado (no nosso exemplo, será no diretório "H", mude para um de sua preferência).

>>E adicionaremos um botão no formulário: nele será colocado informações de entrada e saída do arquivo XML.

Eis o significado de alguns termos que será utilizado na codificação:
XMLDocument1 -> é o componente do XML.
IXmlNode -> é como se fosse o raiz, nele contém os nós filhos do XML.
AddChild -> Adiciona um elemento filho à um nó XML
NodeValue -> Retorna o valor do nó do objeto XML.
Resumindo: na verdade são árvores de nó em qual cada nó é um elemento.

Iniciando o projeto:
Abra o Delphi.
Na aba INTERNET, adicione ao formulário um TXMLDocument.


Adicione um botão, onde será armazenado o código.

Vamos a codificação:
Crie os três procedimentos: procedure CabecalhoXML; procedure Informacao1; procedure Informacao2;
E uma função: CriaDirCaminho(const NomeSubDir: string): boolean;
Declare a variável como global ---> Root : IXmlNode;

Atenção aos códigos:

Esse é o código da função para criar uma Pasta no diretório:
function TForm1.CriaDirCaminho(const NomeSubDir: string): boolean;
var Dir : string;
begin
Dir := 'H:'+'\'+NomeSubDir;

if not DirectoryExists(Dir) then
ForceDirectories(Dir);
end;

Código do procedimento de CabecalhoXML:
procedure TForm1.CabecalhoXML;
var versao : real;
id : integer;
begin
//Transformando "," em "." (vírgula em ponto)
DecimalSeparator := '.';

//Preenchendo variáveis:
id := 12345;
versao:= 1.00;

XMLDocument1.Options := [doNodeAutoIndent];

//Ativa XML
XMLDocument1.Active := True;

//Cabeçalho
XMLDocument1.Encoding := 'utf-8';
XMLDocument1.Version := '1.0';

//Declara o Namespace (se houver)
Root := XMLDocument1.addChild('Delphizinho','http://www.delphizinho.blogspot.com');

//Identificação (se houver)
Root := Root.AddChild('atributos');
Root.Attributes['Id'] := id;
Root.Attributes['versao'] := FormatFloat('0.00', versao);

//Retornando "." para "," (ponto para vírgula)
DecimalSeparator := ',';
end;


Código do procedimento de Informacao1:
procedure TForm1.Informacao1;
begin
//ROOT raiz de informacao1
//AddChild -> Início do nó em informacao1
with Root.AddChild('informacao1') do begin
AddChild('nome').NodeValue := 'Carlos Felizberto Assis';
AddChild('idade').NodeValue := '30';
AddChild('sexo').NodeValue := 'Masculino'
end; //fim de informacao1
end;

Código do procedimento de Informacao2:
procedure TForm1.Informacao2;
begin
//ROOT raiz de informacao2
//AddChild -> Início do nó em informacao2
with Root.AddChild('informacao2') do begin
AddChild('telefone').NodeValue := '(021)5555-5555';
AddChild('celular').NodeValue := '(021)8888-8888';

//AddChild -> Adiciona um nó como filho de outro nó
with AddChild('endereco') do begin
AddChild('rua').NodeValue := 'Rua da Felicidade';
AddChild('numero').NodeValue := 's/n';
AddChild('complemento').NodeValue := 'quadra 5000'
end; //fim de endereco

AddChild('observacao').NodeValue := 'sem observacao';
end; //fim de informacao2
end;

Código do procedimento do Botão:
procedure TForm1.BitBtn1Click(Sender: TObject);
var Nome_Arquivo, Caminho : string;
begin
XMLDocument1.Active := False;
XMLDocument1.XML.Clear;

//Cria pasta Teste1 no diretório H (caso não exista)
CriaDirCaminho('Teste'); //função para criar a pasta Teste

//Preenchendo variáveis:
Nome_Arquivo := ''; //limpa
Nome_Arquivo := 'Teste1'; //Indica nome do arquivo XML
Caminho := ''; //limpa
Caminho := 'H:\Teste'; //Indica caminho a ser gravado o XML

//Chamada do Cabeçalho:
CabecalhoXML;

//Chamada de dados de Informacao1:
Informacao1;

//Chamada de dados de Informacao2:
Informacao2;

//Salva o arquivo XML
XMLDocument1.SaveToFile(Caminho+'\'+Nome_Arquivo+'.xml');

ShowMessage('XML '+Nome_Arquivo+' gerada com sucesso na pasta '+Caminho);
btSair.SetFocus;
end;


Depois de executado o código, o arquivo teste1.xml foi criado (conforme nosso exemplo) no caminho: "H:\Teste".
Dê um duplo clique no arquivo, para visualizá-lo no navegador.

Se for pelo navegador Firefox, basta clicar direto.
Pronto, já está sendo exibido corretamente. Clique nas abas "-" para ocultar e na aba "+" para exibir as informações contidas em cada nó:



Se for visualizar pelo navegador IE, faça:

Serão necessários alguns ajustes, para ele exibir corretamente o XML. Clique na barra amarela:


2- Controle ActiveX, é necessário executar, clique em "Permitir Conteúdo Bloqueado...":


3- Nessa pergunta, responda "SIM":


4- Pronto, já está sendo exibido corretamente. Clique nas abas "-" para ocultar e na aba "+" para exibir as informações contidas em cada nó:


5- Exemplo de algumas informações ocultadas pelas abas:


Fiz testes em alguns navegadores (Safari, Firefox, Chrome, IE), e constatei que o IE e o Firefox são os que o exibem corretamente (em forma identada (com as abas "-" e "+" de controle) e exibe conteúdo do código chamado em xml). Pois os outros mostram a informação direta (somente o resultado final).
----------------------------------------------------------------------------------

Na NF-e este exemplo (da parte do Cabeçalho) ficaria do seguinte modo:
o Root:
Root:= XMLDocument1.addChild('NFe','http://www.portalfiscal.inf.br/nfe');

Definição de Relações. Identificação da NF-e e Versão do Leiaute:
Id:= 'NFe'+chaveNFe; //variável recebe palavra "NFe" + a chave.

Root := Root.AddChild('infNFe');
Root.Attributes['Id'] := id;
Root.Attributes['versao'] := FormatFloat('0.00', versao);

id -> é a chave da NF-e;
versao-> é a versão do aplicativo (conforme o layout estabelece).

Observe, que nesse exemplo, o nó "Delphizinho" é o geral, nele contém: nó "atributos";
O nó "atributos" contém: nó "informacao1" e nó "informacao2";
O nó "informacao2", contém: nó "endereco".

Nos exemplos dos procedimentos Informacao1 e Informacao2, para aplicar à NF-e, é só substituir conforme o layout pede.

Onde obter mais informação sobre XML:
-> Site da W3C http://www.w3c.org/XML/

************************************************
Faça o download do arquivo: XML.rar
************************************************

"Uma viagem de mil léguas começou
com o primeiro passo." Lao Tsé.

20 comentários:

Anônimo disse...
17 de agosto de 2009 às 11:48

Me foi muito útil :) ty

Anônimo disse...
17 de agosto de 2009 às 16:16

vlw brother quebrou um galhao

Anônimo disse...
26 de setembro de 2009 às 12:02

Muito informativo. Obrigado.

Anônimo disse...
18 de dezembro de 2009 às 15:57

da dando um erro [Warning] principal.pas(38): Return value of function 'TForm1.CriaDirCaminho' might be undefined

Delphizinho disse...
21 de dezembro de 2009 às 10:25
Este comentário foi removido por um administrador do blog.
Delphizinho disse...
21 de dezembro de 2009 às 14:18

Sobre o erro "Return value of function... might be undefined":

No exemplo do download, a Função CriaDirCaminho, está setada, para o diretório H.
Se não existir o diretório H, dará erro.
Então no código fonte, basta trocar o diretório H, por outro de sua preferência.

Anônimo disse...
28 de abril de 2010 às 10:55

Alguem sabe Como assinar o conteudo de uma string em Delphi, a Prefeitura Sao Paulo pede isso para validar o envio de RPS

2º - Converta a cadeia de caracteres ASCII para bytes.
3º - Gere o HASH (array de bytes) utilizando SHA1.
4º - Assine o HASH (array de bytes) utilizando RSA-SHA1.

O 4º processo nao consegui fazer alguem teria aluma informaçao pra me ajudar.

se tiverem me envie via email:suporterd@hotmail.com A/C Luis

Anônimo disse...
21 de maio de 2010 às 20:03

Boa Noite,

Meu nome é Nelson, estou começando agora xom XML. Tenho uma duvida!!! Se eu for usar um banco de dados como por exemplo (Interbase), como farei essa rotina para capturar mais de um lancamento? Se alguem tiver uma luz eu agradeço.

Meu e-mail é nelsoncaetanos@msn.com

Anônimo disse...
21 de maio de 2010 às 20:08

No comentario acima não me espressei direiro. Estou querendo usar seu exemplo acima para criar XML para envio de Arquivos XML no padrao TISS da ANS.

Anônimo disse...
2 de junho de 2010 às 17:23

Valeu pela aula.. Já estava quase desistindo da NFE. Muito bom!

Conhecer, Explorar e Viver [CEV] disse...
5 de março de 2011 às 14:06

xmlns:xsi o que eh isso e como adicionar ao xml.
grato,

aamc

Unknown disse...
15 de junho de 2011 às 21:49

Muito bom! Valeu!

Anônimo disse...
23 de maio de 2012 às 23:58

Ótimo tutorial!
Muito Obrigado!
A Internet precisa de mais conteudos como este!

Unknown disse...
14 de junho de 2012 às 17:01

Valeu !

Anônimo disse...
6 de setembro de 2012 às 15:03

muito orbigado por este exemplo tudoe certo
testandoaqui agora com o banco de dados firebird
lincolnvga@hotmail.com

Anônimo disse...
30 de setembro de 2012 às 11:53

Valeu cara! Excelente tutorial! me ajudou demais!
Se vc tiver em seu blog um exemplo como esse de como importar o xml, me ajudaria bastante tambem, mas de qualquer forma farei pesquisas!
Otimo trabalho! obrigado...

Anônimo disse...
11 de novembro de 2013 às 17:24

Beleza garoto!!

Anônimo disse...
17 de abril de 2015 às 09:56

Sei que o poste é bastante antigo mas será que alguém pode me dar uma ajuda? Segui as dicas pra gerar a XML mas quando abro ela no notepad ela esta toda identada e preciso que ela fique numa unica linha igual modelo que sefaz aceite, ja tentei por NodeIdentStr='', e também desativei o doNodeAutoIdent e ele continua identando.

Gavel disse...
9 de outubro de 2016 às 16:16

Muito útil e Altruísta( ajuda Social sem pretensão de lucros ) da sua parte amigo. Eu também adoro ajudar o próximo. Quando terminar de montar a minha NFe colocarei aqui todo o código.

MARCOS CARVALHO disse...
28 de agosto de 2018 às 18:48

Ola pessoal, boa tarde, alguem pode me passar algum material a respeito.
Fico muito agradecido.
marcos_visual@hotmail.com

Postar um comentário