Algumas pessoas têm me procurado com muitas dúvidas sobre gerar um arquivo XML; mas, ultimamente, principalmente, como fazer para ler os dados de um XML. Já mostrei como fazer isso usando o utilitário que acompanha o Delphi “XML Mapper”; o qual uso muito (veja o post) quando preciso integrar um arquivo XML com meu sistema de forma definitiva.

Outra forma de executar a leitura parcial ou total de um arquivo XML é usando o componente TXMLDocument; com ele vc. pode buscar facilmente a informação que vc precisa dentro do arquivo; no código exemplo, que disponibilizo abaixo: vamos ler os itens do arquivo exemplo gerado no post “Dados XML como começar” (poderia ser usado para ler os itens da sua NF-e com pequenos ajustes):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
procedure TForm1.Button32Click(Sender: TObject);
var vXMLDoc: TXMLDocument;
    NodePai,NodeSec,NodeTmp: IXMLNode;
    nome, codigo: WideString;
begin
  // Cria a variável baseada no TXMLDocument
  vXMLDoc := TXMLDocument.Create(self);
 
  // Le conteúdo do arquivo XML informado 
  vXMLDoc.LoadFromFile('EnviNFe.xml');
  // Poderia ser uma URL como abaixo:
  //vXMLDoc.FileName := 'http://www.caiooliveira.com.br/?feed=rss2';
  //vXMLDoc.Active := True;
 
  // Vou colocar os dados no memo apenas como exemplo
  Memo.lines.Add( '-------------------------------------------------');
  Memo.lines.Add( 'Vamos inserir num campo memo (apenas para ver o resultado do teste');
  Memo.lines.Add( VXMLDoc.XML.Text +#13+#13 );
 
  // Aqui eu peço para encontrar a primeira ocorrencia da Tag <det>>
  NodePai := vXMLDoc.DocumentElement.childNodes.First.ChildNodes.FindNode('det');
  // Esse nó vai ser usado no LOOP
  NodeSec := NodePai;
  // Posiciona o primeiro elemento encontrado
  NodeSec.ChildNodes.First;
  repeat
    // referencia a tag <prod> dentro de <det>
    NodeTmp  := NodeSec.ChildNodes['prod'];
    // da pra ver que é um XML resumido da NFe (so temos uma tag <prod> para cada <det> então não precisaria da linha abaixo
    // agora se tivéssemos mais de uma seria o caso de posicionar também na primeira ocorrencia.
    NodeTmp.ChildNodes.First;
    repeat
      // pega os dados que vc quiser dentro da tag <prod>
      nome := NodeTmp.ChildNodes['cProd'].text;     // posso ler assim
      codigo := NodeTmp.ChildValues['cEan'];        // ou assim
 
      // vamos inserir no Memo os dados
      Memo4.Lines.Add('-----------------------------------------------');
      Memo4.Lines.Add( nome+' ---- '+codigo );
 
      // vai para a proxima ocorrência <prod> (se houvesse)
      NodeTmp := NodeTmp.NextSibling;
    until NodeTmp = nil;
    // vai para a proxima ocorrência <det>
    NodeSec := NodeSec.NextSibling;
  until NodeSec = nil;
end;

Posts Relacionados

Tags: ,



74 Comentários to “Lendo o XML com o TXMLDocument”

  1. William | outubro 21st, 2008 at 9:10

    Bom dia Caio! Como sua dica de usar
    o xml mapper, deu certo, mas, imple
    mentando no Delphi 7, não consegui,
    vi este exemplo que você passou, ja
    tinha tentado de algumas formas dife
    rentes usar este “FindNode”, mas nao
    obtive sucesso em nenhuma dela, imple
    mentei este exemplo q vc passou, e
    nao obteve sucesso tbm, da o erro de
    “access violation address…”, tentei
    de algumas outras formas, mas nao
    consegui, qualquer uma das duas formas
    me ajudaria, poderia me ajudar, algum
    exemplo?

  2. admin | outubro 21st, 2008 at 9:49

    Olá Willian,

    Todos os exemplos foram testados no Delphi 7. Faz o seguinte, testa o exemplo primeiro exatamente como ele está; para isso vc vai ter que ler o post “Dados x XML como começar” veja ali como gerar o arquivo XML usado nesse exemplo. Em seguida, use esse exemplo e vai implementando o seu XML até dominar o recurso. Não se esqueça de incluir as UNITS (xmldoc, xmlintf).

    Sds,

  3. Manoel Ribeiro | outubro 29th, 2008 at 15:38

    Olá, estou com o problema que tu citou, preciso implementar a NFe até dezembro, tenho um tempo razoável, mas nunca trabalhei com XML.
    já li aquele arquivo teu XML como começar, mas teria como tu citar mais alguns exemplos de como percorrer o xml (eu conheço como é a estrutura).
    E como eu comecei esta semana a pensar em implementar a NFe gostaria de saber se tu sabes onde estão os laioutes da NFe. Está dificil de encontrar

    Brigadão.

  4. admin | outubro 29th, 2008 at 16:17

    Olá Manoel Ribeiro,

    Se você está começando agora, eu diria que a primeira coisa à fazer é dar uma boa lida no “Manual de Integração” versão atual (2.0.2) e procure entender bem a estrutura da NF-e. Existe material importante no “Blog da NF-e” não deixe de dar uma olhada lá. Nós temos publicado aqui dicas sobre as principais dificuldades encontradas. Outra coisa, o tempo é curto, pois, existem muitos detalhes à serem implementados. Nós fizemos a implementação em três meses aproximadamente; hoje já existem mais informações e material para lhe auxiliar; porém comece o quanto antes.

    Para “ler” o XML vc pode começar usando o exemplo desse post. Veja também o post “XML Mapper ..” outra forma de interpretar o XML diretamente para o ClientDataSet da sua aplicação.

    Sds,

  5. Marcos | novembro 12th, 2008 at 8:48

    Bom dia caio, estou tentando usar este procedimento para ler meus arquivos xml, mas estou com problema… O mesmo problema relatado pelo William, sendo que usei inteiramente o seu exemplo, buscando o xml do post Dados XML como começar. Adicionei as units e continua sempre com o mesmo problema… alguma resolução?
    O problema ocorre na linha com o código “NodeSec.ChildNodes.First;”

  6. admin | novembro 12th, 2008 at 10:46

    Olá Marcos,

    O exemplo acima está funcional. Faz o seguinte, acesse o post “Dados XML como começar”; gere o XML do exemplo que está ali. E depois use esse mesmo arquivo para testar essa função aqui. Eu procurei inclusive usar o mesmo arquivo no exemplo para facilitar.

    Esse exemplo deve funcionar também, em qualquer arquivo XML válido da NF-e.

    Sds, Caio

  7. Claudemir | novembro 25th, 2008 at 15:37

    Olá Caio,

    Td blz? Ta meio sumido, rsss…

    Caio parabéns pela iniciativa de disponibilizar td este farto marial sobre NF-e. Estou usando muito dele.

    Sobre o post Lendo o XML com o TXMLDocument, estou com o mesmo problema do colega Marcos.
    Qdo o codigo chega no metodo “NodeSec.ChildNodes.First” da erro.

    Fiz 1 de book on the table, e notei q no momento q vc tenta atribuir o result do metodo FindNode, ela vem com Nil.

    Dai peguei o codigo do seu outro post “Dados XML como começar”, e funcionou certinho…

    Fiquei intrigado pq funciona num e não funciona noutro…

    Olhando XML notei q vc usa o codigo sobre XML sem a TAG de envio de LOTE, e no q eu to tentando olhar
    tem esta TAG.

    Tb notei q as TAG inicias estão diferentes.

    No meu codigo tem a TAG no inicio do XML e ja no seu ele esta no nivel de root, acredito pq é apenas 1 NF.

    Agora são não descobri como contornar isso…

    Valeu.

  8. Caio | novembro 25th, 2008 at 16:46

    Olá Claudemir,

    Tudo bem? Ultimamente 100% desenvolvendo. Repare que ali o sistema faz diferenciação de maiúsculas/minúsculas e eu utilizei a tag “cEan” para compatibilizar com o exemplo de código anterior; mas, quando no XML da NFe ela deve ser escrita como “cEAN” isso vai causar erro quando vc. tenta ler um XML da NFe válido.

    Modifique o codigo de exemplo;

    de:

    // referencia a tag <prod> dentro de <det>
        NodeTmp  := NodeSec.ChildNodes['prod'];
        // da pra ver que é um XML resumido da NFe (so temos uma tag <prod> para cada <det> então não precisaria da linha abaixo
        // agora se tivéssemos mais de uma seria o caso de posicionar também na primeira ocorrencia.
        NodeTmp.ChildNodes.First;
        repeat
          // pega os dados que vc quiser dentro da tag <prod>
          nome := NodeTmp.ChildNodes['cProd'].text;     // posso ler assim
          codigo := NodeTmp.ChildValues['cEan'];        // ou assim
     
          // vamos inserir no Memo os dados
          Memo4.Lines.Add('-----------------------------------------------');
          Memo4.Lines.Add( nome+' ---- '+codigo );
     
          // vai para a proxima ocorrência <prod> (se houvesse)
          NodeTmp := NodeTmp.NextSibling;
        until NodeTmp = nil;
        // vai para a proxima ocorrência <det>
        NodeSec := NodeSec.NextSibling;
      until NodeSec = nil;

    Para:

    NodePai := vXMLDoc.DocumentElement.childNodes.First.ChildNodes.FindNode('det');
      NodeSec := NodePai;
      NodeSec.ChildNodes.First;
      repeat
        NodeTmp  := NodeSec.ChildNodes['prod'];
        NodeTmp.ChildNodes.First;
          nome := NodeTmp.ChildNodes['cProd'].text;     // posso ler assim
          codigo := NodeTmp.ChildNodes['xProd'].text;
          if nome <> '' then
          begin
          Memo4.Lines.Add('-----------------------------------------------');
          Memo4.Lines.Add( nome+' ---- '+codigo );
          end;
          NodeTmp := NodeTmp.NextSibling;
          NodeSec := NodeSec.NextSibling;
      until nome = ''

    Modifiquei para que leia os itens de qualquer XML NF-e válido. Deve resolver o problema.

    abraços!

  9. Claudemir | novembro 25th, 2008 at 19:02

    Td bem Graças a Deus, obrigado.

    Qto a TAG maiusculo/minusculo, eu até sabia, mas não tinha me atentado…

    Mas o erro ainda persiste, qdo executa o metodo:

    NodePai := vXMLDoc.DocumentElement.childNodes.First.ChildNodes.FindNode(‘det’);

    O NodePai, retorna nil! logo o resto do exemplo não vai funcionar.

    No seu exemplo, vc tem apenas 1 NODE, e na NF-e real até chegar na TAG tem 3 NODEs.

    Pelo q entendi teria q posicionar obrigatoriamente nesta TAG, mas não sei pq não ta trazendo.

    Imagino q ela funcione tipo o IniFile, ou seja, e faço a chamada e ele me devolve o conteudo.

    Se quiser te envio o XML, pra vc ver ai.

    Valeu.
    Claudemir

  10. Caio Oliveira | novembro 26th, 2008 at 8:05

    Com o código modificado acima vc. deveria conseguir ler os itens de qualquer XML válido da NF-e. Eu testei com vários XML de NF-e gerados pelo sistema aleatóriamente. Me envie o seu arquivo para que possa dar uma olhada.

    Sds

  11. Claudemir | novembro 26th, 2008 at 13:14

    Caio,

    Enviei no seu email.

    Obrigado.

  12. Caio Oliveira | novembro 26th, 2008 at 14:42

    Olá Claudemir,

    Dá uma verificada no seu XML, pois, ele não passou no validador (usei o assinadorRS para validar).

    Mas, independente disso dá prá usar o exemplo acima; apenas altere o código do exemplo destacado abaixo:

    de:

    NodePai := vXMLDoc.DocumentElement.childNodes.First.ChildNodes.FindNode('det');
    NodeSec := NodePai;
    NodeSec.ChildNodes.First;

    para:

    NodePai := vXMLDoc.DocumentElement.ChildNodes.FindNode('infNFe');
    NodeSec := NodePai.ChildNodes.FindNode('det');
    NodeSec.ChildNodes.First;

    Sds,

  13. Caio Oliveira | novembro 26th, 2008 at 15:42

    Olá Claudemir,

    Desculpe percebi agora que vc. está tentando ler o arquivo do LOTE de envio. O Programa exemplo anterior lia dentro do arquivo da NFe independente apenas. Modifique o código conforme segue que vai funcionar para esse arquivo também:

      NodePrim := vXMLDoc.DocumentElement.ChildNodes.FindNode('NFe');  // acrescentar essa linha
      NodePai := NodePrim.ChildNodes.FindNode('infNFe'); // modifique aqui.
      NodeSec := NodePai.ChildNodes.FindNode('det');

    Sds, Caio

  14. claudemir | novembro 26th, 2008 at 20:30

    Caio,

    Agora sim, show do bola garoto. Parabéns + 1 vez!

  15. Fernando | dezembro 1st, 2008 at 7:43

    Caio
    Estou tentando ler o arquivo recibo, para obter no nro do recibo, dentro da tag , já tentei varias formas, se você já fez, qualquer dica será bem vinda.
    Antecipadamente agradeço.

  16. Fernando | dezembro 1st, 2008 at 7:45

    mandei as tags, mas elas não apareceram tag pai e tag de dados.

  17. Fernando | dezembro 1st, 2008 at 7:46

    “infRec” e “nRec”

  18. admin | dezembro 1st, 2008 at 8:05

    Olá Fernando,

    Veja o post publicado agora hà pouco. Acho que é exatamente o que estava procurando.

    Sds,

  19. Fernando | dezembro 1st, 2008 at 8:32

    ok, consegui.
    procedure TfmEsFNFe.btCanNClick(Sender: TObject);
    var
    wsDoct: WideString;
    xmlDoc: TXMLDocument;
    NodePai, NodeSec, NodeTmp: IXMLNode;
    begin
    wsDoct := mmReci.Text;
    if(wsDoct”)then begin
    xmlDoc := TXMLDocument.Create(self);
    xmlDoc.XML.Add( wsDoct );
    xmlDoc.Active := True;
    NodePai := xmlDoc.DocumentElement.childNodes.FindNode(‘infRec’);
    if(NodePai=nil)then showmessage( ‘erro node pai ‘ );
    edReci.Text := NodePai.ChildNodes['nRec'].text;
    end
    else
    MessageDlg( ‘Queira informar o Lote a ser enviado na Área de Dados…’, mtError, [mbOk], 0)
    end;

  20. Adriano Cavalcanti Parisi | dezembro 1st, 2008 at 10:23

    Olá Caio.

    A TAG PIS quando vou validar aparece o seguinte erro:
    The element ‘PIS’ in namespace “http://www.portalfiscal.inf.br/nfe” has invalid child element ‘PISQte’ in namespace “http://www.portalfiscal.inf.br/nfe”, pq esta acontecendo esse erro?

    Atenciosamente.

  21. Caio | dezembro 1st, 2008 at 16:15

    Olá Adriano,

    Esse erro indica que vc adicionou um tag inválida; no caso a tag “PISQte” deve ser escrita como “PISQtde”.

    Sds

  22. Titanius | dezembro 19th, 2008 at 12:52

    Amigos, preciso pegar a Tag e copiar ela inteira pra uma variável, para depois poder incluir várias delas no xml, como faço isso?

    Exemplificando melhor…

    Tenho um xml pré-montado, com todas as tags, incluindo a tag , quando vou passar os itens, tenho que criar várias tags para cada item, então estou querendo copiar o conteúdo da para uma variavel.. e depois só adicionar ela, entenderam?

    Obrigado

    []s

  23. admin | dezembro 19th, 2008 at 13:28

    Titanius,

    Veja esse exemplo, deve lhe ajudar (http://www.caiooliveira.com.br/?p=72)

    Sds,

  24. Sidney Souza | janeiro 12th, 2009 at 15:29

    onde posso conseguir esse arquivo XLM que você utiliza nos exemplos pois estou usando um que tenho mas talvez por conta disso está apresentando alguns erros

  25. admin | janeiro 12th, 2009 at 15:43

    Veja o post: http://www.caiooliveira.com.br/?p=64.

  26. César | janeiro 17th, 2009 at 15:30

    Caio, gostaria de agraqdecer pelo texto… Passei os dois ultimos dias procurando isso na net, apesar de não usar para a finalidade apresentada por vc me serviu perfeitamente.

    Obrigado,
    César Dias

  27. Alencar | fevereiro 17th, 2009 at 21:08

    Boa Noite Caio.

    Tche tive dificuldade em identificar as tags q devo informar, nas do exemplo q são ‘det’, ‘prod’, ‘cprod’ e ‘cEan’. Tenho essa dificuldade pois sempre o penso de usar o xml como uma tabela tipo registro e campo, next, first… e essas coisas assim. pois ainda não me caiu na mente. Se tu precisar posso te mandar o arquivo xml q tenho com um lote aprovado.

    Att

  28. Caio | fevereiro 18th, 2009 at 1:27

    Olá Alencar,

    Entendo sua dificuldade, no começo é complicado entender o conceito; estávamos muito acostumados com aquela vidinha simples de While Not Eof…next…né?

    O código abaixo demonstra como fazer o loop no retorno de consulta do lote e deve lhe ajudar a entender melhor esse conceito. Adicionei alguns comentários para que pudesse se posicionar melhor.

    var ...
    begin
      vXMLDoc := TXMLDocument.Create(self);
      try
      // le os dados do arquivo salvo
      vXMLDoc.LoadFromFile('c:\tempo\nfe\retornoProdocoloNfe.xml');
      // ou simplesmente pega a string retWS que contem o XML retorno
      // vXMLDoc.xml.Add(retWS);
      // vXMLDoc.active = true;
     
      // l o arquivo do recibo da NFe
      motivo := vXMLDoc.DocumentElement.ChildNodes['xMotivo'].text;
     
      // posicionamos aqui na tag "protNFe" e em seguida
      // vamos percorrer cada tag "infProt" pegando os 
      // protocolos de retorno de cada NFe.
      NodePai := vXMLDoc.DocumentElement.ChildNodes.FindNode('protNFe');
      NodeSec := NodePai.ChildNodes.FindNode('infProt');
     
      // posiciona no primeiro item (o velho first);
      NodeSec.ChildNodes.First;
     
      // repeat....until  (como o velho while condicao)
      // repete enquanto encontrar dados de protocolo no arquivo.
      repeat
         chaveacesso := NodeSec.ChildNodes['chNFe'].text;
         protocolo := NodeSec.ChildNodes['nProt'].text;
         datahora := NodeSec.ChildNodes['dhRecbto'].text;
         motivo := NodeSec.ChildNodes['xMotivo'].text;
         status := NodeSec.ChildNodes['cStat'].text;
     
         // inserido aqui apenas para testar mostrando os dados no MEMO.
         // quando a NF-e autorizada. Voce pode inserir por exemplo o código
         // para salvar os dados do retorno na sua base.
         if status = '100' then
          Memo.Lines.Add( protocolo+' ---- '+datahora+' - '+motivo );
     
         //  proximo registro (o velho Next)
         NodeSec := NodeSec.NextSibling;
     
      until NodeSec = nil;
      finally
         VXMLDoc.free;
      end;
    end;
  29. Alencar | fevereiro 18th, 2009 at 13:40

    Oi Caio.

    Minha surra ainda continua… hehehehe pois esse codigo ele passa só uma vez e pega so a primeira NFe e ignora as outras

    Att

  30. admin | fevereiro 18th, 2009 at 14:14

    Olá Alencar,

    Ok, me envia uma cópia de um recibo de envio (o XML) para que eu teste o código nele pra vc.

    Sds,

  31. Caio | fevereiro 18th, 2009 at 17:40

    Olá Alencar,

    Agora vai, eu havia criado um arquivo apenas para simular o seu problema (e criei o arquivo diferente do retorno da consulta original, por isso não funcionou).

    Segue abaixo o código:

    begin
      vXMLDoc := TXMLDocument.Create(self);
      // le os dados do arquivo salvo
      vXMLDoc.LoadFromFile('c:\tempo\navcom\nfe\retConsLote_001c.xml');
      // ou simplesmente pega a string retWS que contem o XML retorno
      // vXMLDoc.xml.Add(retWS);
      // vXMLDoc.active = true;
     
      // ou para ler o arquivo do recibo da NFe
      motivo := vXMLDoc.DocumentElement.ChildNodes['xMotivo'].text;
      NodePai := vXMLDoc.DocumentElement.ChildNodes.FindNode('protNFe');
     
      // posiciona no primeiro item (o velho first);
      NodePai.ChildNodes.First;
     
      // repeat....until  (como o velho while condicao)
      // repete enquanto encontrar dados de protocolo no arquivo.
      repeat
         NodeSec := NodePai.ChildNodes.FindNode('infProt');
         chaveacesso := NodeSec.ChildNodes['chNFe'].text;
         protocolo := NodeSec.ChildNodes['nProt'].text;
         datahora := NodeSec.ChildNodes['dhRecbto'].text;
         motivo := NodeSec.ChildNodes['xMotivo'].text;
     
         // inserido aqui apenas para testar mostrando os dados no MEMO.
         //if protocolo  '' then
          Memo4.Lines.Add( chaveacesso+'-&gt; '+protocolo+' ---- '+datahora+' - '+motivo );
     
         // esse seria o Next
         NodePai := NodePai.NextSibling;
     
      until NodePai = nil;
    end;

    Sds,

  32. Alencar | fevereiro 19th, 2009 at 14:46

    Funcionou Caio,

    Beleza não tenho palavras, e no que eu puder ser util é so tu pedir, Valeu mesmo muito Obrigado

    Att

  33. Eduardo | março 10th, 2009 at 13:27

    Caio,
    So nao consigo ler o no (para saber a data de emissao ) de arquivos recebidos de nossos fornecedores.
    Os arquivos estao todos autorizados e formatacao OK
    Todos os outros dados ja estamos lendo.
    Grato
    []´s Eduardo

  34. Eduardo | março 10th, 2009 at 13:52

    Caio,
    A mensagem foi truncada…
    Completando nao consigo ler o no (ide) para ler a data de emissao (dEmi)
    Grato
    []´s Eduardo

  35. admin | março 10th, 2009 at 15:22

    Olá Eduardo,

    Segue um exemplo do codigo abaixo:

     
    .... 
     
    NodePai := vXMLDoc.DocumentElement.ChildNodes.FindNode('infNFe');
      Id := NodePai.GetAttributeNS('Id','');
      Memo.Lines.Add( 'Id:' +Id );
     
      Nodeide := NodePai.ChildNodes.FindNode('ide');
      Memo.Lines.Add( 'dEmi = '+Nodeide.ChildNodes['dEmi'].text);
      Memo.Lines.Add( 'dSaiEnt = '+Nodeide.ChildNodes['dSaiEnt'].text);
     
    ...
  36. Eduardo | março 19th, 2009 at 16:40

    Caio,
    Ao ler o meu arquivo o exemplo retorna um erro no Id =(access voliation)
    Id = WideString OK?

    Pode ser o meu arquivo?

    Grato
    []´s Eduardo

  37. Edelson | abril 14th, 2009 at 8:50

    Bom dia Caio!
    Existe alguma maneira de fazer uma pesquina de um valor contido numa tag utilizando o XMLDocument?
    Por exemplo, tenho um XML com a seguinte estrutura:

    Como eu faço para retornar o ID_CLIENTE = 4 por exemplo?
    Tenho que fazer um loop e ler todos os registros, ou existe alguma maneira mais “inteligente”?

    Abraços!

  38. Edelson | abril 14th, 2009 at 8:51

    Acho que o blog não aceita tags né? rs
    Não apareceu nada na mensagem que eu enviei…

  39. Caio | abril 14th, 2009 at 15:11

    Olá Edelson,

    Dá uma olhada na matéria desse link, acho que deve lhe ajudar (http://www.marcosdellantonio.net/2007/05/29/utilizando-xpath-no-delphi/).

    Sds,

  40. Luis Fernando ferrari | abril 17th, 2009 at 12:13

    Ola Caio nao sei mas o que fazer tenho um aquivo XML como segue abaixo

    96293
    1
    2009-04-14 13:51:14
    -23.5489
    -46.5655
    0
    21.8536
    1
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    1
    1
    0
    NA
    2067
    27
    76
    0
    1
    0
    1
    0
    1
    NA
    NA
    NA
    38966

    0
    0
    0
    0

    tenho que pegar as tags como ex: serial, type, timestap, etc mostrar e gravar no banco usando o seu exemplo da nf da um erro de violação de acesso
    veja o codigo :

    procedure TForm1.FileListBox1Click(Sender: TObject);
    var vXMLDoc: TXMLDocument;
    NodeRec,NodeTmp: IXMLNode;
    wserial, wdatahora: WideString;
    begin
    arq_xml.text := FileListBox1.FileName ;
    XMLDocument1.FileName := trim(arq_xml.text) ;
    XMLDocument1.LoadFromFile(arq_xml.Text); //Le Arquivo XML’);
    Memo.lines.Add( XMLDocument1.XML.Text +#13+#13 );
    if arq_xml.text = ” then
    else
    TreeView1.LoadFromFile(arq_xml.text);
    NodeRec := XMLDocument1.DocumentElement.childNodes.First.ChildNodes.FindNode(’serial’) ;
    // Prepara para ler os dados da tag
    NodeRec := XMLDocument1.DocumentElement.ChildNodes.FindNode(’serial’); /// aqui ele nao esta carregando o node
    // Lendo os campos da tag
    wserial := NodeRec.ChildNodes['SERIAL'].Text ; // aqui da o erro de violação de acesso
    end;

    Pode me ajudar ou tem um jeito mais simples pq por clientdataset nao consegui tambem

  41. Luis Fernando ferrari | abril 17th, 2009 at 12:17

    o arquivo xml nao foi correto vou te dar o exemplo de como esta

    96293

  42. admin | abril 17th, 2009 at 15:01

    Olá Luis,

    Conforme XML exemplo que vc me enviou via e-mail, o codigo poderia ser assim:

    var vXMLDoc: TXMLDocument;
        NodePai: IXMLNode;
        serial, latitude, longitude, vel: WideString;
     
    begin
      vXMLDoc := TXMLDocument.Create(self);
      vXMLDoc.LoadFromFile('c:\tempo\positions.xml');
     
      NodePai := vXMLDoc.DocumentElement.ChildNodes.FindNode('POSITION');
      NodePai.ChildNodes.First;
      repeat
          serial := NodePai.ChildNodes['SERIAL'].text;
          latitude := NodePai.ChildNodes['LATITUDE'].text;
          longitude := NodePai.ChildNodes['LONGITUDE'].text;
          vel := NodePai.ChildNodes['VEL'].text;
          NodePai := NodePai.NextSibling;
     
          Memo.Lines.Add( serial+', '+latitude+', '+longitude+', '+vel )
      until NodePai = nil;
     
    end;
  43. Luis Fernando ferrari | abril 17th, 2009 at 15:46

    Vc é o cara muito obrigado deu certo

  44. Marcio | maio 14th, 2009 at 12:36

    Olá Caio , Pessoal da pagina .

    Fiz toda uma rotina para leitura completa do NFE, para gerar a DANFE com o Quick Report , mais ainda nao faco ideia de como fazer isso .

    para quem desejar pode acompanhar o codigo em :
    http://malubri.blogspot.com/2009/05/lendo-o-xml-da-nfe-com-o-xmldocument.html

    Att. MArcio

  45. gleyson | junho 9th, 2009 at 13:30

    Boa tarde Caio não sei se pode me ajudar estou utilizando o seu código e alterando para dar entrada no estoque do meu rp atraves do xml ou seja atraves do xml da nfe insiro os dados do produto e do fornecedor no meu bando de dados segue abaixo parte do código.
    bem até aqui está funcionando bem meu problema e os impostos pois tenho as tagues antes de chegar nos dados e sempre dá acsess violatin nestas tagas
    -
    -
    -

    grato e gostaria de agradecer pelo blog pois está sendo o meu norte.

    // Aqui eu peço para encontrar a primeira ocorrencia da Tag >
    NodeNFEide := vXMLDoc.DocumentElement.childNodes.First.ChildNodes.FindNode(‘ide’);
    ide_cUF := NodeNFEide.ChildValues['cUF'];
    ide_cNF := NodeNFEide.ChildValues['cNF'];
    ide_natOp := NodeNFEide.ChildValues['natOp'];
    ide_indPag := NodeNFEide.ChildValues['indPag'];
    ide_mode := NodeNFEide.ChildValues['mod'];
    ide_serie := NodeNFEide.ChildValues['serie'];
    ide_nNF := NodeNFEide.ChildValues['nNF'];
    ide_dEmi := NodeNFEide.ChildValues['dEmi'];

    // Aqui eu peço para encontrar a primeira ocorrencia da Tag >
    NodePai := vXMLDoc.DocumentElement.childNodes.First.ChildNodes.FindNode(‘det’);

    // Esse nó vai ser usado no LOOP
    NodeSec := NodePai;
    // Posiciona o primeiro elemento encontrado
    NodeSec.ChildNodes.First;
    repeat
    // referencia a tag dentro de
    NodeTmp := NodeSec.ChildNodes['prod'];
    NodeTmp.ChildNodes.First;

    repeat
    // pega os dados que vc quiser dentro da tag
    if NodeTmp.ChildValues['xProd'] Null then
    begin
    nome := NodeTmp.ChildValues['xProd'];

    if NodeTmp.ChildValues['CFOP'] Null then
    begin
    NaturezaOperacao := NodeTmp.ChildValues['CFOP'];
    end;

    if NodeTmp.ChildValues['cProd'] Null then
    begin
    codigo := NodeTmp.ChildValues['cProd'];
    end;

    if NodeTmp.ChildValues['NCM'] Null then
    begin
    ClassificacaoFiscal := NodeTmp.ChildValues['NCM'];
    end;

    if NodeTmp.ChildValues['uCom'] Null then
    begin
    Unidade := NodeTmp.ChildValues['uCom'];
    end;

    if NodeTmp.ChildValues['qCom'] Null then
    begin
    Quantidade := NodeTmp.ChildValues['qCom'];
    Quantidade := StringReplace(Quantidade, ‘.’, ‘,’, [rfReplaceAll]);
    qtd := StrtoFloat(Quantidade);
    Quantidade := FormatFloat(‘#######0.’,qtd);
    end;

    if NodeTmp.ChildValues['vUnCom'] Null then
    begin
    ValorUnitario := NodeTmp.ChildValues['vUnCom'];
    ValorUnitario := StringReplace(ValorUnitario, ‘.’, ‘,’, [rfReplaceAll]);
    vlrunt := StrtoFloat(ValorUnitario);
    ValorUnitario := FormatFloat(‘#######0.00′,vlrunt);
    end;

    end;

    // vai para a proxima ocorrência
    NodeTmp := NodeTmp.NextSibling;
    until NodeTmp = nil;
    // vai para a proxima ocorrência
    NodeSec := NodeSec.NextSibling;
    until NodeSec = nil;

  46. gleyson | junho 9th, 2009 at 13:32

    - imposto
    - ICMS
    - ICMS10

    As tagues que está dando erro são estas elas não aparecerão no codigo acima
    Grato gleson

  47. admin | junho 10th, 2009 at 11:10

    Guenta ai que lhe respondo mais tarde…

  48. Marcelo | agosto 24th, 2009 at 18:45

    Caio,

    estou tentando fazer a leitura do retorno de lote.
    Está me dando dois erros.
    O primeiro é que ele diz que o documento não está Ativo.
    resolvi colocando vXMLDoc.Active := True;

    o Segundo me dá na hora de ativar o documento.
    Project NF.exe raised exception class EDOMParseError with message ‘Se encontró un carácter no válido en el contenido del text.
    Line:1
    <’

    É leitura do retWS mesmo.

    Marcelo

  49. admin | agosto 24th, 2009 at 23:03

    Olá Marcelo,

    Algumas UF estão devolvendo acentos no arquivo XML de retorno o que causa o erro na hora de abrir o arquivo. Antes de abrir o arquivo de retorno, executa uma função para remover caracteres inválidos.

    Sds,

  50. Tiago | setembro 21st, 2009 at 14:40

    Por Favor Caio,

    Não estou conseguindo fazer o Until de meu Repeat funcionar…

    O que acontece é que ele não sai do loop.

    Veja.

    type
    TNodes = Record

    Itens : IXMLNode ; //Itens da NF

    End;

    Nodes.Itens.ChildNodes.First;
    Repeat

    Nodes.Itens := Nodes.Itens.NextSibling ;

    Until( Nodes.Itens = nil );

    Muito obrigado por sua ajuda!

  51. admin | setembro 23rd, 2009 at 14:18

    Olá Thiago,

    O “repeat/until” funciona mais ou menos como o “While x = y do begin … end”; ou seja, no seu caso, enquanto o Nodes.Itens não atingir um valor “nulo” o loop não cessará. Verifique o código novamente, se quiser me passa o código como vc. está usando que dou uma olhada pra vc.

    Sds

  52. Danilo | setembro 25th, 2009 at 17:26

    Caio,

    Através deste artigo consegui fazer a leitura e a escrita de arquivos XML.

    Mas quando tento ler várias vezes um nó não estou conseguindo.

    Conteúdo do XML:

    0012
    Pharmalink
    SAN001
    24092009170913
    00

    20490
    28763118000190
    000001
    3299
    623
    2676
    623
    72990

    PHARMALINK (SAN001) – VENDA
    DATA: 24/09/2009 HORA: 17:31:13
    ESTAB: 28763118000190 TERM: 0000000001
    AUT. 0000072990 TRANS. 0000020490
    DROG NOSSA CAIXA
    CART.: XXXXXXXXX158 VALOR: R$6,23

    ______________________________________
    Ze da Silva

    Código:

    nodeRetorno := xmlLeitura.DocumentElement.ChildNodes.FindNode(‘linhas’);
    nodeRetorno.ChildNodes.First;
    repeat
    ShowMessage(nodeRetorno.ChildNodes['linha'].Text);
    nodeRetorno := nodeRetorno.NextSibling;
    until ( nodeRetorno = nil );

    Tenho que ler todas as linhas dentro da tag

  53. Danilo | setembro 25th, 2009 at 17:29

    ops,

    no XML eu tenho uma tag LINHAS e dentro dela várias tags LINHA com o conteúdo acima.

  54. admin | setembro 29th, 2009 at 0:23

    Danilo,

    Envia o arquivo XML no meu e-mail e o ponto onde está o problema que dou uma olhada pra vc.

    sds

  55. Danilo | setembro 29th, 2009 at 11:01

    Obrigado a atenção.

    Já enviei no seu email.

  56. Wanderson Robert | outubro 15th, 2009 at 9:29

    Ola, tenho tido problmas para importacao de um XML (cupons) gerado pelo winmfd2,tentei aplicar conforme exemplo, mas nao consigo, se puder agradeco auxilo.
    Abaixo estrutura do XML

    13/10/2009 00:12:33
    4205
    3309

    1
    0000000000001
    ALCOOL COMUM
    4,038
    1,86
    7,51
    FF

    7,51
    0,00
    0,00
    7,51
    7,51
    0,00

    13/10/2009 00:14:08
    4207
    3310

    1
    0000000000001
    ALCOOL COMUM
    40,651
    1,86
    75,61
    FF

    75,61
    0,00
    0,00
    75,61
    0,00
    0,00

    4213

  57. Wanderson Robert | outubro 15th, 2009 at 9:33

    a estutura do xml é:

    documentos

    cupom_fiscal
    hora_inicio
    coo
    ccf
    venda_de_item
    ordem
    codigo
    descricao
    quantidade
    valor_unitario
    valor_bruto
    aliquota
    venda_de_item
    subtotal
    acrescimo
    desconto
    total
    soma_pgto
    troc
    cupom_fiscal

    cancelamento_de_cupom_fiscal
    coo_do_cupom_cancelado
    cancelamento_de_cupom_fiscal

    documentos

  58. Wanderson Robert | outubro 15th, 2009 at 9:43

    nodepai:= vXMLDoc.DocumentElement.childNodes.First.ChildNodes.FindNode(‘documentos’);

    xDocumentos := nodepai;
    xDocumentos.ChildNodes.First;
    xcupons := xdocumentos.ChildNodes['cupom_fiscal'];
    xcupons.ChildNodes.First;
    repeat
    application.ProcessMessages;
    Cupons.Insert;
    Cuponscupom_fiscal.Value :=strtoint(xcupons.ChildNodes['coo'].Text);
    cuponsemissao.AsDateTime :=StrtoDate(Copy(xcupons.ChildNodes['hora_inicio'].Text,1,10));
    cuponshora.Value :=Strtotime(Copy(xcupons.ChildNodes['hora_inicio'].Text,12,8));
    cuponsvalor.Value :=StrtoFloat(xcupons.ChildNodes['total'].Text);
    cupons.Post;
    { xitens:= xcupons.ChildNodes['venda_de_item'];
    // xitens.ChildNodes.First;
    repeat
    application.ProcessMessages;
    Cupons_itens.Insert;
    Cupons_itenscupom_fiscal.Value :=strtoint(xcupons.ChildNodes['coo'].Text);
    cupons_itensordem.Value :=strtoint(xitens.ChildNodes['ordem'].Text);
    cupons_itenscodigo.Value :=strtoint(xitens.ChildNodes['codigo'].Text);
    cupons_itensdescricao.Value :=xitens.ChildNodes['descricao'].Text;
    cupons_itensquantidade.Value :=StrtoFloat(xitens.ChildNodes['quantidade'].Text);
    cupons_itensvalor_unitario.Value :=StrtoFloat(xitens.ChildNodes['valor_unitario'].Text);
    cupons_itensvalor_bruto.Value :=StrtoFloat(xitens.ChildNodes['valor_bruto'].Text);
    cupons_itensaliquota.Value :=xitens.ChildNodes['aliquota'].Text;
    cupons_itens.Post;
    xitens.NextSibling;
    until xitens=nil ;}
    xcupons.NextSibling;
    until xcupons=nil;

  59. admin | outubro 15th, 2009 at 18:26

    Envia o XML no meu e-mail.

  60. Tonieto | outubro 24th, 2009 at 11:46

    Caio,

    não estou conseguindo escrever o codigo correto para percorrer a tag e pegar as informacoes sobre as duplicatas de um xml autorizado. Veja trecho do xml.

    22552009-11-17333.0822552009-11-27333.0822552009-12-02333.08

    Help me, my friend.

  61. Jeová | dezembro 17th, 2009 at 9:46

    Caio, Obrigado por compartilhar seu conhecimento conosco, continue assim e que o criador lhe abençoe e continue dando paciência para nos ajudar.
    Grato,

  62. Theo Duarte | dezembro 18th, 2009 at 8:54

    Caio, uma duvida, e no caso de eu ter que ler o xml, porém de uma variável string, ao invés de um arquivo.

  63. Fábio Spies | janeiro 6th, 2010 at 9:22

    Caio, muito obrigado esse texto foi extremamente util e aplicável.
    Porém pra mim só ficou uma dúvida:
    Em uma NF-e existe a tag assim:

    Conforme os exemplos acima consigo retornar tranquilamente o numero do protocolo e a chave as tags nProt e chNFe.
    Mas não consigo pegar a informação que está no próprio campo: <infProt Id="…quero pegar essa string aqui…"
    Sei que reflete o numero do protocolo precedido da expressão NFe, mas tenho que comparar esse conteúdo com o nProt, pois utilizando o programa emissornfe da sefaz, constatei que algumas notas geram nesse campo a chave da nota ao invés do protocolo e isso causa erro nos importadores.
    Desta forma pretendo fazer uma ferramenta para identificar os xml que tem esse erro.
    Desde já agradeço.

  64. Fábio Spies | janeiro 6th, 2010 at 10:17

    Ops, consegui agora usando o comando:

    NodePai := vXMLDoc.DocumentElement.ChildNodes.FindNode(‘protNFe’);
    NodeSec := NodePai.ChildNodes.FindNode(‘infProt’)
    infProtid := NodeSec.GetAttributeNS(‘Id’,”);

  65. admin | janeiro 11th, 2010 at 10:51

    Olá Theo,

    Nesse caso, basta adicionar a string à propriedade XML do TXMLDocument; como no código abaixo:

    vXMLDoc.XML.Text := string;

    sds,

  66. André Batista | fevereiro 6th, 2010 at 10:25

    Bom caio!
    Estou estudando os código a listados mas não estou conseguindo obter êxito nas técnicas aqui apresentedas, gostaria de saber como faça para pegar o Id da Nfe.

  67. Joao Henrique | abril 5th, 2010 at 17:36

    Olá…

    Só um comentario…
    Na de claração da variável, é melhor usar:

    ao invés de:
    var vXMLDoc: TXMLDocument;

    usar:
    var vXMLDoc: IXMLDocument;

    Pois só assim eu consigui dar um “Free” no vXMLDOC:

    finally
    vXMLDoc:=nil;

    []´s

  68. Adriano | abril 8th, 2010 at 13:49

    Olá Caio,

    Estou montado um sistema para entrada das XML no ERP, tudo estava tranquilo quando me deparece com a seguinte tag:

    -
    -
    5426
    2955.75
    2955.75

    -
    5426/1
    2010-04-27
    985.25

    -
    5426/2
    2010-05-04
    985.25

    -
    5426/3
    2010-05-11
    985.25


    A tag esta ok mas o meu problema o na hora do repeat nas tag vc poderia me dar uma ajuda

    Desde já agradeço

  69. Adriano | abril 8th, 2010 at 15:16

    Caio,

    Consegui aqui montar tava me confundindo, abaixo segue como montei

    vNoDup := vNoCobr.ChildNodes['dup'];
    vNoDup.ChildNodes.First;
    repeat

    vNDup := vNoDup.ChildNodes['nDup'].Text;

    vNoDup := vNoDup.NextSibling;
    until vNoDup = nil;

    XML TAG FATURA

    vNoCobr – tag COBR da NF-e
    vNoDup – tag DUP dentro da TAG COBR
    vNDup – é o elemento NDUP

  70. Thiago Balbino | abril 16th, 2010 at 16:40

    2
    0603
    310000008609925
    104
    Lote processado
    31

    2
    0600
    31100405323734000125550010000005100000005104
    2010-04-16T10:18:12
    FvLExuNtVzd0THV0yuVHSxEMCRI=
    405
    Rejeicao: Codigo do pais do emitente: digito invalido

    pessoal como faço pra ler os valores no cabeçalho do XML

    –> 2
    –> 0603
    –> 310000008609925
    –> 104
    –> Lote processado
    –> 31

    esses campos att.

  71. Odoni | abril 24th, 2010 at 23:34

    Oi Caio, preciso da sua ajuda.

    o meu programa esta lendo mais itens do que existem no xml. ai da pau. só tem um produto no xml.
    como eu faço para jogar os dados lidos do xml para o rave ou QR?
    obrigado.

  72. maria silvia | maio 14th, 2010 at 14:47

    Boa Tarde,

    Estou Lendo um XML da NFe utilizando o seu codigo, no delphi 2007, porem ele lê alguns arquivos e outros ele dá ACCESS VIOLATION qdo ele vai pegar o numero da nota no XML.

    estou fazendo assim:

    vXMLDoc := TXMLDocument.Create(self);
    // Le conteúdo do arquivo XML informado
    vXMLDoc.LoadFromFile(ClientDataSet1.FieldByName(‘ARQUIVO’).AsString);

    NodePai := vXMLDoc.DocumentElement.childNodes.First.ChildNodes.FindNode(‘ide’);
    //strNeNF – variavel do tipo wideString
    strNeNF := NodePai.ChildNodes['nNF'].text;
    // ele da erro na linha acima… porém so em alguns xmls

    vc pode me ajudar?

  73. Ricardo Gondim | junho 3rd, 2010 at 23:37

    Estou usando esta rotina para ler varios arquivos xml e atualiza a chave da Nfe do meu arquivo em mysql. Só que ao executar pela segunda vez ela me retorna o seguinte erro: O sistema não pode localizar o Objeto especificado..

    procedure TForm1.Button1Click(Sender: TObject);
    var vXMLDoc: TXMLDocument;
    NodePrim, NodePai, NodeCabecalhoXML, NodeRec, NodeRec2, NodeSec, NodeTmp: IXMLNode;
    Nome: WideString;
    index:integer;
    Arquivo :String;
    begin
    Table1.Open;
    Table2.Open;
    vXMLDoc := TXMLDocument.Create(self);
    OpenDialog1.FileName := ”;
    OpenDialog1.Title := ‘Selecione a NFE’;
    OpenDialog1.DefaultExt := ‘*-nfe.XML’;
    OpenDialog1.Filter := ‘Arquivos XML (*.XML)|*.XML|Todos os Arquivos (*.*)|*.*’;
    OpenDialog1.InitialDir := ‘c:\automa\nfe\saidas\’;
    if OpenDialog1.Execute then
    begin
    for index:=0 to OpenDialog1.Files.Count-1 do
    begin
    ListBox1.Items.Add(ExtractFileName( OpenDialog1.Files[index]));
    Arquivo := (listbox1.items.Strings[index]);
    vXMLDoc.LoadFromFile(arquivo);
    vXMLDoc.Active := True;
    Memo.Lines.Clear;
    Memo4.Lines.Clear;

    try
    // vXMLDoc.LoadFromFile(‘C:\xml\Delphi_caio\EnviNFe.xml’);

    Memo.lines.Add( ‘————————————————-’);
    Memo.lines.Add( VXMLDoc.XML.Text +#13+#13 );

    NodePrim := vXMLDoc.DocumentElement.ChildNodes.FindNode(‘NFe’);
    NodePai := NodePrim.ChildNodes.FindNode(‘infNFe’);
    NodeCabecalhoXML := NodePai.ChildNodes['ide'];
    {Dados do nó dentro do nó pai IDE}
    Memo4.Lines.Add( ‘Código da UF ‘+ NodeCabecalhoXML.ChildNodes['cUF'].Text);
    Memo4.Lines.Add( ‘Código Numérico ‘+ NodeCabecalhoXML.ChildNodes['cNF'].Text);
    Memo4.Lines.Add( ‘Natureza Operação ‘+ NodeCabecalhoXML.ChildNodes['natOp'].Text);
    Memo4.Lines.Add( ‘Ind. Forma Pgto. ‘+ NodeCabecalhoXML.ChildNodes['indPag'].Text);
    Memo4.Lines.Add( ‘Modelo Doc. Fiscal ‘+ NodeCabecalhoXML.ChildNodes['mod'].Text);
    Memo4.Lines.Add( ‘Série da Nfe ‘+ NodeCabecalhoXML.ChildNodes['serie'].Text);
    Memo4.Lines.Add( ‘Nº Doc. Fiscal ‘+ NodeCabecalhoXML.ChildNodes['nNF'].Text);
    // Lê os dados de “protNFe”
    NodeRec := vXMLDoc.DocumentElement.ChildNodes.FindNode(‘protNFe’);
    NodeRec2:= NodeRec.ChildNodes.FindNode(‘infProt’);
    Memo4.Lines.Add( ‘Chave Nfe ‘+ NodeRec2.ChildNodes['chNFe'].Text);

    MskNota.TExt := NodeCabecalhoXML.ChildNodes['nNF'].Text;
    MskNota.TExt := Zeros(MskNota.TExt);
    Table1.IndexName := ‘SAIDAS3′;
    If Table1.FindKey([MskNota.TExt])= True Then
    begin
    Table1.Edit;
    Table1ChVNfe.Text := NodeRec2.ChildNodes['chNFe'].Text;
    Table1.post;
    end;
    Table2.IndexName := ‘NOTAS2′;
    If Table2.FindKey([MskNota.TExt])= True Then
    begin
    Table2.Edit;
    Table2ChVNf.Text := NodeRec2.ChildNodes['chNFe'].Text;
    Table2.post;
    end;

    { NodePrim := vXMLDoc.DocumentElement.ChildNodes.FindNode(‘NFe’); // acrescentar essa linha
    NodePai := NodePrim.ChildNodes.FindNode(‘infNFe’); // modifique aqui.
    NodeSec := NodePai.ChildNodes.FindNode(‘det’);
    NodeSec.ChildNodes.First;
    repeat
    NodeTmp := NodeSec.ChildNodes['prod'];
    nome := NodeTmp.ChildNodes['cProd'].text; // posso ler assim
    if nome ” then
    begin
    Memo4.Lines.Add( NodeTmp.ChildNodes['cProd'].text +’ ‘+ NodeTmp.ChildNodes['xProd'].text + ‘ ‘+NodeTmp.ChildNodes['CFOP'].text + ‘ ‘+NodeTmp.ChildNodes['qCom'].text + ‘ ‘+NodeTmp.ChildNodes['vUnCom'].text + ‘ ‘+NodeTmp.ChildNodes['vPro'].text);
    end;
    NodeTmp := NodeTmp.NextSibling;
    NodeSec := NodeSec.NextSibling;
    until nome = ” }
    finally
    end;
    end;
    vXMLDoc.Free;
    end;
    Table1.Close;
    Table2.Close;
    end;

  74. TBerth | agosto 10th, 2010 at 8:54

    Olá, Eu estou carregando o arquivo xml da seguiinte maneira:
    vXMLDoc.LoadFromFile(nome_arquivo);

    mas quando tento carregar um XML que contenha espaços como (‘1350900_v1.10-procNFe – 1.xml’), não lê!

    É possível eu carregar um XML que contenha espaços em seu nome??

    Obrigado

Faça um comentário