Percorrer um XML

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

marcos.gurupi
Usuário Nível 4
Usuário Nível 4
Mensagens: 939
Registrado em: 06 Jul 2004 11:53
Localização: Gurupi-TO

Percorrer um XML

Mensagem por marcos.gurupi »

Caros, preciso percorrer um arquivo XML. Peguei um exemplo aqui no forum mas nao esta dando certo. Gostaria que alguem me desse uma luz, o q estou fazendo errado. Segue abaixo os detalhes:

Arquivo XML:

Código: Selecionar todos

<?xml version="1.0"?>
<xml>
  <exportacao>
    <itens id="0001">
      <ecnpj>19448850000185</ecnpj>
      <prevenda>4407</prevenda>
      <codproduto>0000071</codproduto>
      <ean></ean>
      <descricao>PRODUTO PADRAO DO SISTEMA 2</descricao>
      <unidade>UN</unidade>
      <quant>2</quant>
      <vlrunit>98</vlrunit>
      <totalitem>196</totalitem>
      <codtrib>03</codtrib>
      <ncm>95049090</ncm>
      <cest></cest>
    </itens>
    <itens id="0002">
      <ecnpj>19448850000185</ecnpj>
      <prevenda></prevenda>
      <codproduto>0000072</codproduto>
      <ean></ean>
      <descricao>PRODUTO PADRAO DO SISTEMA 3</descricao>
      <unidade>UN</unidade>
      <quant>5</quant>
      <vlrunit>9</vlrunit>
      <totalitem>45</totalitem>
      <codtrib>03</codtrib>
      <ncm>85176262</ncm>
      <cest>2111000</cest>
    </itens>
  </exportacao>
</xml>
Com o codigo abaixo eu apenas estou pegando o primeiro item.

Código: Selecionar todos

   cStr := fOpen( cArq )
   oXML := TXMLDocument():New( cStr, HBXML_STYLE_NOESCAPE ) 
    IF oXML:nError != HBXML_ERROR_NONE 
        Msgstop( "xml com problema " + Str( oXML:nError ) ) 
		MonitorExecuta := 1
		Select(Areant)
		RETURN 
   ENDIF 

   oPedido := oXML:findfirst( "itens" ) 
   IF oPedido == NIL 
      Msgstop( "TAG itens não localizada." ) 
      MonitorExecuta := 1
      Select(Areant)
		RETURN 
   ENDIF 
   oIterator := TXmlIterator():New( oPedido )
   DO WHILE .T.
      DO WHILE .T. 
         oCurrent := oIterator:Next() 
         IF oCurrent == NIL 
            EXIT 
         ELSE 
         IF oCurrent:cName == "ecnpj" 
               veCNPJ := oCurrent:cData
         ELSEIF oCurrent:cName == "prevenda" 
               vPreVenda := oCurrent:cData
         ELSEIF oCurrent:cName == "codproduto" 
               vcodproduto := oCurrent:cData 
         ELSEIF oCurrent:cName == "ean" 
               vean := oCurrent:cData 
         ELSEIF oCurrent:cName == "descricao" 
               vdescricao := oCurrent:cData  
               msginfo(vDescricao)
            ELSEIF oCurrent:cName == "unidade" 
               vunidade := oCurrent:cData
            ELSEIF oCurrent:cName == "quant" 
               vquant := oCurrent:cData
            ELSEIF oCurrent:cName == "vlrunit" 
               vVlrUnit := oCurrent:cData
            ELSEIF oCurrent:cName == "totalitem" 
               vtotalitem := oCurrent:cData
            ELSEIF oCurrent:cName == "codtrib" 
               vcodtrib := oCurrent:cData
            ENDIF 
         Endif
   ENDDO
  oPedido := oXML:findnext( "itens" ) 
  If oPedido == NIL 
      exit 
  EndIf 
Enddo
Marcos Roberto
NetService Software
Avatar do usuário
Wanderlei
Usuário Nível 3
Usuário Nível 3
Mensagens: 196
Registrado em: 25 Jan 2008 13:19
Localização: Goiânia - GO

Percorrer um XML

Mensagem por Wanderlei »

Bom dia Marcos,
Este exemplo peguei aqui no forum.
LerXmlNFe.prg
(12.84 KiB) Baixado 643 vezes
Wanderlei Cardoso
Analista / Programador
XHarbour + GtWvW + FiveWin + HwGui + Firebird
Skype: cwanderlei
cwanderlei@yahoo.com.br
(62)98171-3059 - whatsapp

Imagem
Avatar do usuário
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Percorrer um XML

Mensagem por Toledo »

Apenas para complementar a mensagem do Wanderlei, veja no tópico abaixo um outro exemplo:

https://pctoledo.org/forum/viewto ... 685#p62685

- Neste exemplo altere a linha 2 com o caminho e nome do seu arquivo xML.

- Na linha 7 troque "det" por "itens".

- Das linhas 12 até 24, troque por:

Código: Selecionar todos

veCNPJ:= oXmlDetPro:find( 'ecnpj' ):cData
vPreVenda:= oXmlDetPro:find( 'prevenda' ):cData
vcodproduto:= oXmlDetPro:find( 'codproduto' ):cData
etc...
Se for necessário verificar se uma tag existe, antes de pegar o seu valor, veja as linhas 22, 23 e 24.

Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Percorrer um XML

Mensagem por JoséQuintas »

Veja se facilita.

Postei tempos atrás uma funçãozinha que ajuda no caso de XMLs, uma pra gerar e outra pra ler.
Se souber o formato do XML, acho mais prático por ela do que por outro método.

Pense no seguinte..... o XML é separado em blocos, cada bloco tem <bloco></bloco>, e também blocos dentro de blocos.
Pra encontrar um bloco, é pesquisar de "<bloco" até "</bloco>"

Então basta uma simples função que localize o início/fim do bloco, e separe o bloco.
( Estou digitando e criando durante o post, é aproximadamente o que deveria ser, mas pode conter erro )

Código: Selecionar todos

FUNCTON XmlNode( cXml, cBloco )
   cText := cXml
   nInicio := At( "<" + cBloco, cText )
   cText := Substr( cText, nInicio )
   nFim := At( "</" + cBloco + ">", cText )
   cText := Substr( cText, 1, nFim + Len( cBloco ) + 3 )
   RETURN cText
A partir daí, só usar.
Exemplo:

Código: Selecionar todos

cXmlEmitente := XmlNode( cXml, "emitente" )
   cNome      := XmlNode( cXmlEmitente, "nome" )
   cEndereco := XmlNoce( cXmlEmitente, "endereco"
   cCidade    := XmlNode( cXmlEmitente, "cidade" )

cXmlDestinatario := XmlNode( cXml, "destinatario" )
   cNome := XmlNode( cXmlDestinatario, "nome" )
   cEndereco := XmlNode( cXmlDestinatario, "endereco" )
   cCidade    := XmlNode( cXmlDestinatario, "cidade" )
Lógico... tem os casos de <nota id=dsfdfdf versao=fdjfjdsfd>
Vai ajustando a rotina até resolver as variações, incluindo a de pegar apenas o conteúdo entre as tags, sem os delimitadores <bloco></bloco>
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Percorrer um XML

Mensagem por alxsts »

Olá!

Pessoalmente prefiro usar a classe TXmlDocument() e seus métodos. É mais seguro pois ao carregar o XML ela já verifica a integridade do mesmo, retornando um atributo que pode ser testado. Além disto, trata todas as situações que teriam que ser tratadas em uma rotina própria, inclusive tags vazias, do tipo <tag/> (não tem a tag de aberturam somente a de fechamento). Enfim, é reinventar a roda...
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Percorrer um XML

Mensagem por JoséQuintas »

Se considerar que o Windows já tem isso há muito tempo, quando criaram TXmlDocument() também reinventaram a roda.

Eu já usava isso no tempo do Clipper, importando notas de fornecedor, então não havia nada pronto.

Existem muitos editores de texto, muitas linguagens de programação, LIBs gráficas pro Harbour, IDEs pro Harbour, ...
Existe Harbour 3.2, 3.4, xHarbour.... distribuições Linux...
No final, reinventar a roda é muito comum.

E tem certos casos onde reinventam uma roda quadrada,,, faz parte.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
marcos.gurupi
Usuário Nível 4
Usuário Nível 4
Mensagens: 939
Registrado em: 06 Jul 2004 11:53
Localização: Gurupi-TO

Percorrer um XML

Mensagem por marcos.gurupi »

Bom dia!
Pra encerrar o tópico. Gostaria de dizer que o problema estava no meu cdigo fonte. Em itens de pedido eu estava condicionando a inclusao de um novo item se n existisse o numero do pedido cadastrado. Isso fazia com que o sistema so incluise 1 item de kda pedido. Depois dessa pisada na bola foi tudo de primeira. Obr a todos pelas colaborações!
Marcos Roberto
NetService Software
Avatar do usuário
Mario Mesquita
Usuário Nível 4
Usuário Nível 4
Mensagens: 613
Registrado em: 08 Dez 2009 13:47
Localização: Rio de Janeiro

Percorrer um XML

Mensagem por Mario Mesquita »

Bom dia, pessoal.

Dei up no post pois estou pesquisando a melhor forma de ler um XML e gravar num DBF.

A ideia do Quintas é interessante, mas creio que necessite de experiencia em tratar o formato, como foi dito, em caso de elementos vazios, etc. Nesse caso, a TXMLDOCUMENT pode ser melhor se não se tem prática com o XML.

Para usar a classe precisa de algum include ou algo assim? Pra variar, a pouca e não muito clara documentação do Harbour dificulta um pouco. Num velho tutorial de xHarbour, um exemplo de rotina tem uma linha:

#include "hbXml.ch"

Para o Harbour isso ainda é necessário?

Quem tiver alguma dica, desde já agradeço.

Saudações e bom domingo a todos,
Mario.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Percorrer um XML

Mensagem por JoséQuintas »

XmlNode() é apenas uma função.

Tem uma classe na sefazclass pra ajudar no que quer fazer.

Importante:
pra entender um pouco o uso de XmlNode(), vá direto na FUNCTION XmlToDocNfeEmi().
Ela faz bastante uso de XmlNode()

https://github.com/JoseQuintas/sefazcla ... lClass.prg

De uma forma geral, essa classe na SefazClass é com tudo pronto, pra fazer algo assim:

Código: Selecionar todos

oDoc := XmlToDoc( MemoRead( "arquivo.xml" ) )
? oDoc:Emitente:Nome
? oDoc:Emitente:CNPJ
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Mario Mesquita
Usuário Nível 4
Usuário Nível 4
Mensagens: 613
Registrado em: 08 Dez 2009 13:47
Localização: Rio de Janeiro

Percorrer um XML

Mensagem por Mario Mesquita »

Boa tarde a todos.

Quintas, que legal, uma classe completa pra tratar XML. Bom pra estudar XML e como trabalhar com classes de objeto.

Não trabalho muito com classes, ranço do Clipper acho. É bom ver quem sabe. Muito obrigado!

Fazendo uns testes aqui com o TXmlDocument() pra ver como ia ser. Acho que ele funcionou, mas deu um erro de array, talvez eu tenha errado o nome de algum elemento, vou conferir e reporto como foi.

Estou tentando jogar direto num Grid. Tá meio tosco, mas vamos ver se isso resolve.

Novamente, obrigado por compartilhar seu conhecimento.

Abraço,
Mario.
Avatar do usuário
Mario Mesquita
Usuário Nível 4
Usuário Nível 4
Mensagens: 613
Registrado em: 08 Dez 2009 13:47
Localização: Rio de Janeiro

Percorrer um XML

Mensagem por Mario Mesquita »

Bom dia a todos.

Amigos, consegui fazer a leitura do XML pelo método TXMLDocument() e pôr os dados em um Grid para posterior gravação em uma tabela.

Obrigado pelas dicas e passando a correria, vou ler mais sobre XML, que ao visto será cada vez mais usado em troca de informações.

Abraços,
Mario.
Avatar do usuário
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

Percorrer um XML

Mensagem por rubens »

Mário tem jeito de postar um exemplo do código aí?
Tô trabalhando justamente nisso...

Obrigado
"Eu e minha casa servimos ao Senhor e você ???"
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Percorrer um XML

Mensagem por janio »

Eu uso a classe do Quintas para LER xml de FORNECEDOR!

Muuuuito facil!

viewtopic.php?f=54&t=17413&start=15

Janio
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Percorrer um XML

Mensagem por Jairo Maia »

Jânio, acho que o link que você postou não tem nada a ver com o que está sendo discutido aqui não. Aqui está sendo discutido a leitura e extração de informação do XML, por exemplo: ler o XML de compra, e verificar se houve alteração no valor de custo do item, atualizar estoque pegando a quantidade, se o produto não está cadastrado cadastrar e já com os dados fiscais com base no CFOP e CST/CSOSN, etc...

Também estou trabalhando nisso (extrair dados do XML). Por isso seria interessante se o Mário postasse o que conseguiu, talvez ajude.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

Percorrer um XML

Mensagem por rubens »

Bom dia...

Eu já faço assim em harbour e lendo o xml com memoread... Mas com a classe creio que fica muito melhor ...
Agora tô implantando em Minigui com a opção de baixar o xml pela chave.
Do jeito que já faço em harbour inclusive o sped já fica quase pronto...
LeXML.prg
(31.58 KiB) Baixado 587 vezes
Rubens
"Eu e minha casa servimos ao Senhor e você ???"
Responder