Página 1 de 1

Converter XML para DBF

Enviado: 30 Mar 2005 15:18
por Dudu_XBase
Alguém tem conhece algum programa para conversão de um XML para DBF ou Txt ??

Enviado: 02 Abr 2005 05:11
por rochinha
Amiguinho

Não sei qual sua intenção com um arquivo XML mas analise a rotina abaixo.

Eu uso ela para ler arquivos .OFX com dados de minha conta bancária, neste caso do Unibanco.

Não é dificil entender o funcionamento dos dados dentro de um arquivo XML, pois os dados estarão separados por tags.

Código: Selecionar todos

...
        M->REGISTRO := RECNO()
        M->DESDE    := DATA
        M->IDCONTA  := IDCONTA

        MENSAGEM('Verificando arquivos de retorno...')
        aDIRECTORY := DIRECTORY("OFX\*.OFX")
        aOFXes     := {}
        FOR I = 1 TO LEN(aDIRECTORY)
            cIDt := SeekIniDt("OFX\"+aDIRECTORY[I,1])
            cFDt := SeekFimDt("OFX\"+aDIRECTORY[I,1])
            AADD( aOFXes, PADR(aDIRECTORY[I,1],13)+" "+cIDt+" "+cFDt )
        NEXT

        SELE SALDO
        M->IDOFX := SPACE(15) // ALLTRIM(M->IDCONTA) + ".OFX"
        //M->DESDE   := DATE()
        CREATE CONTROL GROUPBOX 'group3' AT MAXROW()-8,52 SIZE  5, 25 TEXT " Dados da Conta "      STYLE NORMAL // RECESSED
        @ MAXROW()-6,54 say 'Arquivo'
        @ MAXROW()-5,54 say 'Desde'
        @ MAXROW()-6,64 GET M->IDOFX PICT "@!@S10" ;
                        WHEN SAYIT('Digite o nome do arquivo de transa‡„o.') ;
                        VALID PSQ_TAB3( 8, 24, aOFXes , "IDOFX" ) // VALID PSQOFX(M->IDOFX)
        @ MAXROW()-5,64 GET M->DESDE WHEN SAYIT('Digite a DATA de inicio para conciliar.')
        SET CURSOR ON
        READ
        SET CURSOR OFF
        IF LASTKEY() <> 27 .OR. !EMPTY(M->IDOFX)
           //PSQOFX(M->IDOFX)
           CLOSE DATABASES
           //ARQ_PRN1 := ".\BANCOS\" + M->IDOFX
           ARQ_PRN1 := "OFX\" + ALLTRIM(SUBSTR( M->IDOFX, 1, 14 ))
           DBCREATE( "NFOFX2", { { "LI_NHA"  , "C",255, 0 } } )
           DBCREATE( "NFOFX3", { { "IDBANCO"   , "C",20, 0 } , ;
                                 { "IDCONTA"   , "C",20, 0 } , ;
                                 { "AGENCIA"   , "C", 6, 0 } , ;
                                 { "DATA"      , "D", 8, 0 } , ;
                                 { "HISTORICO" , "C",45, 0 } , ;
                                 { "DOCUMENTO" , "C",10, 0 } , ;
                                 { "VALOR"     , "N",14, 2 } , ;
                                 { "CREDITO"   , "N",14, 2 } , ;
                                 { "DEBITO"    , "N",14, 2 } , ;
                                 { "TIPO"      , "C", 1, 0 } , ;
                                 { "CONCILIADO", "D", 8, 0 } , ;
                                 { "FECHAMENTO", "L", 1, 0 } } )
           USE NFOFX3 NEW
           USE NFOFX2 NEW
           APPEND FROM &ARQ_PRN1 SDF
           GO TOP
           M->BANKID   := ''
           M->ACCTID   := ''
           M->TRNTYPE  := ''
           M->DTPOSTED := ''
           M->TRNAMT   := ''
           M->FITID    := ''
           M->CHECKNUM := ''
           M->MEMORAND := ''
           M->CABECA   := .F.
           MENSAGEM('Verificando registros...')
           DO WHILE .NOT. EOF()
              IF '<BANKID>' $ LI_NHA
                 M->BANKID := SUBSTR(LI_NHA,9,05)
              ENDIF
              IF '<ACCTID>' $ LI_NHA
                 M->ACCTID := SUBSTR(LI_NHA,9,15)
              ENDIF
              IF '<TRNTYPE>' $ LI_NHA
                 M->TRNTYPE := SUBSTR(LI_NHA,10,40)
              ENDIF
              IF '<DTPOSTED>' $ LI_NHA
                 M->DTPOSTED := CTOD(SUBSTR(LI_NHA,17,2)+'/'+;
                                     SUBSTR(LI_NHA,15,2)+'/'+;
                                     SUBSTR(LI_NHA,11,4))
              ENDIF
              IF '<TRNAMT>' $ LI_NHA
                 M->TRNAMT := VAL(SUBSTR(LI_NHA,9,15))
              ENDIF
              IF '<FITID>' $ LI_NHA
                 M->FITID := SUBSTR(LI_NHA,8,15)
              ENDIF
              IF '<CHECKNUM>' $ LI_NHA
                 M->CHECKNUM := SUBSTR(LI_NHA,11,15)
              ENDIF
              IF '<MEMO>' $ LI_NHA
                 M->MEMORAND := SUBSTR(LI_NHA,7,40)
              ENDIF
              IF '<STMTTRN>' $ LI_NHA
                 SELE NFOFX3
                 APPEND BLANK
                 SELE NFOFX2
              ENDIF
              IF '</STMTTRN>' $ LI_NHA
                 SELE NFOFX3
                 REPLACE IDBANCO    WITH M->BANKID
                 REPLACE IDCONTA    WITH SUBSTR(M->ACCTID,5,9)
                 REPLACE AGENCIA    WITH SUBSTR(M->ACCTID,1,4)
                 REPLACE DATA       WITH M->DTPOSTED
                 REPLACE HISTORICO  WITH STRTRAN(M->MEMORAND,'*','')
                 REPLACE DOCUMENTO  WITH M->CHECKNUM
                 REPLACE VALOR      WITH IIF(M->TRNAMT<0,M->TRNAMT*-1,M->TRNAMT)
                 REPLACE CREDITO    WITH IIF(M->TRNTYPE='C',M->TRNAMT,0)
                 REPLACE DEBITO     WITH IIF(M->TRNTYPE='D',IIF(M->TRNAMT<0,M->TRNAMT*-1,M->TRNAMT),0)
                 REPLACE TIPO       WITH M->TRNTYPE
                 REPLACE CONCILIADO WITH CTOD('  /  /  ')
                 REPLACE FECHAMENTO WITH .F.
                 SELE NFOFX2
              ENDIF
              SKIP
           ENDDO
           SELE NFOFX3
           APPEND BLANK
           SELE NFOFX2
        ENDIF
        USE TRANSACA INDEX TRANS001 NEW
        USE PN       INDEX PN007,PN008 NEW
        USE CONTRCNT NEW
        USE CONTRCTB NEW
        USE CONTAS   INDEX CONTA009,CONTA010,CONTA016,CONTA011,CONTA012,CONTA013,CONTA014,CONTA015,CONTA017,CONTA018,CONTA109,CONTA110 NEW
        USE CORRENTE INDEX CORRE021,CORRE022,CORRE023,CORRE024 NEW
        USE SALDO    INDEX SALDO022 NEW
            SEEK M->IDCONTA  // Pesquisa pela conta
            IF .NOT. FOUND()
               BEEP(); MENSAGEM('Conta nao foi encontrada!', 3)
               SELE CORRENTE                 // Seleciona arquivo de movimentacao de contas
               RETURN .T.
            ENDIF
            M->SALDO   := SALDO->SALDO    // Pega pelos dados da conta
            M->LIMITE  := SALDO->LIMITE   // Pega pelos dados da conta
            //M->IDCONTA := SALDO->IDCONTA
            M->BANCO   := SALDO->BANCO
            M->AGENCIA := SALDO->AGENCIA
        SELE CORRENTE
            MENSAGEM('Adicionando registros ao movimento...')
            APPEND FROM NFOFX3 FOR DATA >= M->DESDE
            SET ORDER TO 1
            #ifdef TRIOART
                   SET FILTER TO CORRENTE->IDCONTA = M->IDCONTA .AND. CORRENTE->TIPO # 'A'
            #else
                   SET ORDER TO 1
                   M->SUBARQ := '_'+substr(ordName(),1,2)+substr(strtran(time(),":",""),4,3)+".NTX"  
                   SubNtx( ordBagName(), M->SUBARQ, M->IDCONTA )
                   SET INDEX TO CORRE021,CORRE022,CORRE023,CORRE024,&SUBARQ.
                   SET ORDER TO 5
                   SET FILTER TO CORRENTE->TIPO # 'A' .AND. CORRENTE->TIPOLAN # 'E'
            #endif
            GO BOTTOM
            SKIP -9
        retorno  = 2
...
Com ela eu abro o arquivo de transferencia, crio uma estrutura para suportar seus dados, analise cada tag de abertura, pegos os dados de cada campo, transformo em dados repassaveis, salvo os dados para a estrutura e transfiro os dados para corrente e atualizo o saldo.

@braços :?)

Enviado: 02 Abr 2005 13:55
por Dudu_XBase
Obrigado Rochinha pela Luz e pela Atenção.
Entendi seu código perfeitamente vlw irmão.

Converter XML para DBF

Enviado: 09 Set 2023 14:11
por JulioNSP
Boa tarde pessoal, este post me interessou porque estou precisando ler os arquivos XML da NFe para um banco de dados Dbase III, alguem sabe como fazer isso? Eu ainda uso o Clipper Summer 87.

Desde já agradeço por qualquer ajuda.

Julio.

Converter XML para DBF

Enviado: 09 Set 2023 14:56
por alxsts
Olá!

No xHarbour e Harbour existem classes que tratam esta questão, como mostrado nos exemplos abaixo, onde se pode ver os códigos para ler um DBF e copiar para um arquivo XML e o inverso.

Certamente não funciona no Summer '87 mas serve como ilustração. Talvez criar um EXE separado para fazer esta importação...
TXmlDocument()
Creates a new TXmlDocument object.

Syntax
TXmlDocument():new( [<nFileHandle>|<cXmlString>], [<nStyle>] ) --> oTXmlDocument

Arguments

<nFileHandle>
This is a file handle of an XML file to read. It is returned from function FOpen().

<cXmlString>
Instead of a file handle, an XML formatted character string can be passed. If the first parameter is omitted, the object has no XML data, but can be used to add XML nodes and create a new XML file (see example).

<nStyle>
This parameter instructs the TXMlDocument object how to read an XML file and/or how to write XML nodes into a file. #define constants listed in Hbxml.ch are used to specify <nStyle>:

Constants for XML object creation
Constant Value Description
HBXML_STYLE_INDENT 1 Indents XML nodes with one space
HBXML_STYLE_TAB 2 Indents XML nodes with tabs
HBXML_STYLE_THREESPACES 4 Indents XML nodes with three spaces
HBXML_STYLE_NOESCAPE 8 Reads and creates unescaped characters in data sections

Note: when the style HBXML_STYLE_NOESCAPE is set, the textual content enclosed in an opening and closing XML tag is scanned for characters that normally must be escaped in XML. This can lead to a considerable longer time for reading the XML data.
The characters to be escaped are single and double quotes ('"), ampersand (&), and angled brackets (<>). If such characters exist in textual content and are not escaped, a parsing error is generated, unless HBXML_STYLE_NOESCAPE is used.

Return
Function TXmlDocument() creates the object and method :new() initializes it.

Description
The TXmlDocument() class provides objects for reading and creating XML files. XML stands for eXtensible Markup Language which is similar to HTML, but designed to describe data rather to display it. To learn more about XML itself, the internet provides very good free online tutorials. The website www.w3schools.com is is a good place to quickly learn the basics on XML.
A TXmlDocument object maintains an entire XML document and builds from it a tree of TXmlNode() objects which contain the actual XML data. The first XML node is stored in the :oRoot instance variable, which is the root node of the XML tree. Beginning with the root node, an XML document can be traversed or searched for particular data. The classes TXmlIteratorScan() and TXmlIteratorRegEx() are available to find a particular XML node, based on its tag name, attribute or data it contains.

Instance variables
:oRoot
Root node of the XML tree.

:nStatus
Status information on XML parsing.

:nError
Error code for XML parsing.

:nLine
Current line number being parsed.

:oErrorNode
TXmlNode object containing illegal XML code.

:nNodeCount
Number of nodes in the XML tree. Methods for XML data manipulation

:read( ... ) --> self
Reads an XML file or string.

:toString( <nStyle> ) --> cXmlString
Creates an XML formatted character string.

:write( <nFileHandle>, [<nStyle>] ) --> self
Creates an XML formatted character string. Methods for searching and navigating

:findFirst( ... ) --> oTXmlNode | NIL
Locates the first XML node containing particular data.

:findFirstRegEx( ... ) --> oTXmlNode
Locates the first XML node containing particular data using regular expressions.

:findNext() --> oTXmlNode | NIL
Finds the next XML node matching a search criteria. Info

See also: TXmlIterator(), TXmlIteratorRegEx(), TXmlIteratorScan(), TXmlNode()

Category: Object functions , xHarbour extensions
Header: hbxml.ch
Source: rtl\txml.prg
LIB: xhb.lib
DLL: xhbdll.dll

Examples

Creating an XML file

Código: Selecionar todos

// The example uses the Customer database and creates an XML file
// from it. The database structure and its records are written
// to different nodes in the XML file. The basic XML tree is this:
//
// <database>
//  <structure>
//   <field .../>
//  </structure>
//  <records>
//   <record>
//    <fieldname> data </fieldname>
//   </record>
//  </records>
// </database>

   #include "hbXml.ch"

   PROCEDURE Main
      LOCAL aStruct, aField, nFileHandle
      LOCAL oXmlDoc, oXmlNode, hAttr, cData
      LOCAL OXmlDatabase, oXmlStruct, oXmlRecord, oXmlField

      USE Customer

      aStruct  := DbStruct()

      // Create empty XML document with header
      oXmlDoc  := TXmlDocument():new( '<?xml version="1.0"?>' )

      // Create main XML node
      oXmlDatabase := TXmlNode():new( , "database", { "name" => "CUSTOMER" } )
      oXmlDoc:oRoot:addBelow( oXmlDatabase )

      // copy structure information to XML
      oXmlStruct := TXmlNode():new( , "structure" )
      oXmlDataBase:addBelow( oXmlStruct )

      FOR EACH aField IN aStruct
         // store field information in XML attributes
         hAttr := { "name" => Lower( aField[1] ), ;
                    "type" => aField[2], ;
                    "len"  => LTrim( Str(aField[3]) ), ;
                    "dec"  => LTrim( Str(aField[4]) )  }

         oXmlField := TXmlNode():new(, "field", hAttr )
         oXmlStruct:addBelow( oXmlField )
      NEXT

      // copy all records to XML
      oXmlNode := TXmlNode():new( , "records" )
      oXmlDataBase:addBelow( oXmlNode )

      DO WHILE .NOT. Eof()
         hAttr      := { "id" => LTrim( Str( Recno() ) ) }
         oXmlRecord := TXmlNode():new( , "record", hAttr )

         FOR EACH aField IN aStruct
            IF aField[2] == "M"
               // Memo fields are written as CDATA
               cData     := FieldGet( Hb_EnumIndex() )
               oXmlField := TXmlNode():new( HBXML_TYPE_CDATA  , ;
                                            Lower( aField[1] ), ;
                                            NIL               , ;
                                            cData               )
            ELSE
               // other fields are written as normal tags
               cData     := FieldGet( Hb_EnumIndex() )
               cData     := Alltrim( CStr( cData ) )
               oXmlField := TXmlNode():new( HBXML_TYPE_TAG    , ;
                                            Lower( aField[1] ), ;
                                            NIL               , ;
                                            cData               )
            ENDIF
            // add field node to record
            oXmlRecord:addBelow( oXmlField )
         NEXT

         // add record node to records
         oXmlNode:addBelow( oXmlRecord )
         SKIP
      ENDDO

      // create XML file
      nFileHandle := FCreate( "Customer.xml" )

      // write the XML tree
      oXmlDoc:write( nFileHandle, HBXML_STYLE_INDENT )

      // close files
      FClose( nFileHandle )
      USE
   RETURN

Reading an XML file

Código: Selecionar todos

// This example uses the Customer.xml file created in the
// prevous example and extracts from it the structure definition
// for the Customer.dbf file.

   PROCEDURE Main
      LOCAL oXmlDoc := TXmlDocument():new()
      LOCAL oXmlNode, aStruct := {}

      oXMlDoc:read( Memoread( "customer.xml" ) )

      oXmlNode := oXmlDoc:findFirst()
      ? oXmlNode:cName

      oXmlNode := oXmlDoc:findFirst( "structure" )
      ? oXmlNode:cName

      oXmlNode := oXmlDoc:findFirst( "field" )

      DO WHILE oXmlNode <> NIL
         // attributes are stored in a hash
         AAdd( aStruct, { oXmlNode:aAttributes[ "name" ]      , ;
                          oXmlNode:aAttributes[ "type" ]      , ;
                          Val( oXmlNode:aAttributes[ "len" ] ), ;
                          Val( oXmlNode:aAttributes[ "dec" ] )  } )

         oXmlNode := oXmlDoc:findNext()
      ENDDO

      AEval( aStruct, {|a| Qout( ValToPrg(a) ) } )
   RETURN

Escape characters in XML

Código: Selecionar todos

// The example demonstrates the effect of HBXML_STYLE_NOESCAPE
// when XML code is created.

   #include "hbXml.ch"

   PROCEDURE Main
      LOCAL oXmlDoc, oXmlNode

      oXmlDoc := TXmlDocument():new( '<?xml version="1.0"?>' )
      oXmlNode:= TXmlNode():new( , "text", , [this must be escaped: "'&<>] )

      oXmlDoc:oRoot:addBelow( oXmlNode )

      ? oXmlDoc:toString()

      ** output:
      // <?xml version="1.0"?>
      // <text>this must be escaped: "&apos;&<></text>

      ? oXmlDoc:toString( HBXML_STYLE_NOESCAPE )

      ** output:
      // <?xml version="1.0"?>
      // <text>this must be escaped: "'&<></text>
   RETURN
--------------------------------------------------------------------------------

Copyright © 2006-2007 xHarbour.com Inc. All rights reserved.

Fonte: xHarbour Language Reference Guide

Converter XML para DBF

Enviado: 09 Set 2023 16:16
por Itamar M. Lins Jr.
Olá!
ler os arquivos XML da NFe para um banco de dados Dbase III
Use a função do José Quintas XMLNODE!
Função pequena que funciona até no clipper. Use AT() ao invéz de hb_at(), hb_default() por pcount() e assim vai mudando para clipper...

Código: Selecionar todos

****************************************
FUNCTION XmlNode( cXml, cNode, lComTag )
****************************************
*
*
   LOCAL nInicio, nFim, cResultado := ""

   hb_Default( @lComTag, .F. )
   nInicio := At( "<" + cNode + ">", cXml )
   IF nInicio == 0
      nInicio := At( "<" + cNode + " ", cXml )
   ENDIF
   // a linha abaixo é depois de pegar o início, senão falha
   IF " " $ cNode
      cNode := Substr( cNode, 1, At( " ", cNode ) - 1 )
   ENDIF
   IF nInicio != 0
      IF ! lComTag
         nInicio := nInicio + Len( cNode ) + 2
         IF nInicio != 1 .AND. Substr( cXml, nInicio - 1, 1 ) != ">" // Quando tem elementos no bloco
            nInicio := hb_At( ">", cXml, nInicio ) + 1
         ENDIF
      ENDIF
      nFim := hb_At( "</" + cNode + ">", cXml, nInicio )
      IF nFim != 0
         nFim -=1
         IF lComTag
            nFim := nFim + Len( cNode ) + 3
         ENDIF
         cResultado := Substr( cXml, nInicio, nFim - nInicio + 1 )
      ENDIF
   ENDIF

   RETURN cResultado
Abaixo uma parte da função de IMPORTAÇÃO de milhares de NFCe, em segundos.

Código: Selecionar todos

cAnoMes := hb_DToC(dIni,"YYMM")
cAnoMes := "29" + cAnoMes
aFilesXml := hb_vfDirectory( cPathXML + cAnoMes + "*.xml" )
nTFiles   := Len(aFilesXML)

For nX := 1 To nTFiles

   IF ++nRefresh == 100
      oBar:Set("Processando, "+lTrim(Str(nX,9))+" De "+lTrim(Str(nTFiles,9))+" arquivo(s) XML na pasta",nX)         
      hwg_processmessage()
      nRefresh :=  0
   ENDIF
          
   cFile   := cPathXML + aFilesXml[ nX, 1 ]
   cArq    := aFilesXml[ nX, 1 ]
   
   cNF     := SubStr(cArq,36,8)
   cAnoMes := SubStr(cArq,03,4) 
   dDta    := CToD( "01" + "/" + SubStr(cAnoMes,3,2) + "/" + SubStr(cAnoMes,1,2) )

   cIniAM  := hb_DToC(dIni,"YYMM")
      
   IF cIniAM == cAnoMes
   
      IF "NFEDFE" $ Upper(cFile)  
         AAdd(aCancel, StrZero(Val(cNF),9) + SubStr(DToS(dDta),1,6) )
         LOOP 
      ENDIF   
      
      IF cab->( dbSeek( StrZero(Val(cNF),9) + SubStr(DToS(dDta),1,6) ) )
         LOOP
      ENDIF
   
   ELSE
      LOOP
   ENDIF
               
   cFile := Hb_MemoRead( cFile )
   
   cBloco := XmlNode( cFile , "ide" ) //Data  
   dhEmi  := hb_ctod(substr(XmlNode( cBloco , "dhEmi" ),1,10),"yyyy-mm-dd")  //<dhEmi>2019-01-31T08:47:58-03:00</dhEmi>
   cNF    := XmlNode( cBloco , "nNF" ) //
   cSerie := XmlNode( cBloco , "serie" )
   
   cBloco := XmlNode( cFile , "infProt" ) //Autorizada ?   
   cChave := XmlNode( cBloco , "chNFe" )
   
   if dhEmi >= dIni .and. dhEmi <= dFim
   else
      loop
   endif

   cMotivo     := XmlNode( cBloco , "xMotivo" )

   cTicket     := XmlNode( cFile , "infCpl" ) 
   
   cTicket     := SubStr(  cTicket ,9,9) 

   IF Upper(SubStr(cMotivo,1,16)) == "AUTORIZADO O USO"
   
      //cTPag       := XmlNode( cFile , "tPag" ) //em 30/08/2023
      
      cBloco      := XmlNode( cFile , "total" ) //Para somar os valores totais da notas

      nVPROD      := Val( XmlNode( cBloco , "vProd" ) )
        
      nVDESC      := Val( XmlNode( cBloco , "vDesc" ) )
     
      nVPIS       := Val( XmlNode( cBloco , "vPIS" ) )
      nVCOFINS    := Val( XmlNode( cBloco , "vCOFINS" ) )
     
      nVNF        := Val( XmlNode( cBloco , "vNF" ) )
                  
      IF !cab->(dbSeek(StrZero(Val(cNF),9)+DToS(dhemi)) )

         cab->(dbAppend())
         cab->situacao :=  "N"
         cab->dia      := dhemi
         cab->chnfe    := cChave
         cab->nfce     := StrZero(Val(cNF),9)
       //cab->ind_pgto := cTPag
         cab->serie    := cSerie
         cab->vProd    := nVPROD
         cab->vdesc    := nVDESC
         cab->vpis     := nVPIS
         cab->vcofins  := nVCOFINS
         cab->vnf      := nVNF
         cab->ticket   := cTicket
         
         cTagPag := XmlNode( cFile , "pag" )
         
         FOR nTP := 1 TO 3
            
            cTPag := XmlNode( cTagPag,'tPag')
            nVPag := Val( XmlNode( cTagPag,'vPag') )
            
            IF Empty(cTPAG)
               Exit
            ENDIF
            
            IF nTP == 1            
               cab->tpag01 := cTPAG
               cab->vpag01 := nVPAG
            ELSEIF nTP == 2            
               cab->tpag02 := cTPAG
               cab->vpag02 := nVPAG    
            ELSEIF nTP == 3
               cab->tpag03 := cTPAG
               cab->vpag03 := nVPAG                              
            ENDIF
            
            cTagPag := StrTran(cTagPag,"tPag",'')
            cTagPag := StrTran(cTagPag,"vPag",'')
            
         NEXT
         
         //Adicionar os itens
         
         FOR nItem := 1 TO 999
             
            cTagDetItemX := 'det nItem="' + Hb_NToS( nItem ) + '"'
            cTagDetItemX := XmlNode( cFile , cTagDetItemX )
            
            //hwg_msginfo("Achou: " + cTagDetItemX + " cTicket: " + cTicket)
             
            IF Empty(cTagDetItemX)
               exit
            ENDIF
            
            nVBC := nPICMS := nVICMS := 0
            nPIPI := nVIPI := nVDesc := nVPIS := nVCOFINS := 0
            cModBCST :=  "" ; cEAN := ""
            nPREDBCST :=  nPMVAST  :=  nVBCST := nPICMSST := nVICMSST := 0
         
            cCProd   := XmlNode(cTagDetItemX, "cProd")
            cEANZero := XmlNode(cTagDetItemX, "cEAN")
            cEAN     := hb_ntos(Val(cEANZero))
            cXPROD   := hb_UTF8ToStr( AllTrim(charone(" ",XmlNode(cTagDetItemX, "xProd") )))
            cNCM     := XmlNode(cTagDetItemX, "NCM")
            cCEST    := XmlNode(cTagDetItemX, "CEST")
            cCFOP    := XmlNode(cTagDetItemX, "CFOP")
            cUCom    := XmlNode(cTagDetItemX, "uCom")
            nQCom    := Val( XmlNode(cTagDetItemX, "qCom") )
            nVUnCom  := Val( XmlNode(cTagDetItemX, "vUnCom") )
            nVDesc   := Val( XmlNode(cTagDetItemX, "vDesc") )

            cTagICMS := XmlNode(cTagDetItemX, "ICMS")
            cOrig    :=      XmlNode(cTagICMS, "orig")            
            cCST     :=      XmlNode(cTagICMS, "CST")            
            nVBC     := Val( XmlNode(cTagICMS, "vBC") )
            nPICMS   := Val( XmlNode(cTagICMS, "pICMS") )
            nVICMS   := Val( XmlNode(cTagICMS, "vICMS") )            
            nVBCST   := Val( XmlNode(cTagICMS, "vBCST") )
            cModBCST :=      XmlNode(cTagICMS, "modBCST") 
            nPMVAST  := Val( XmlNode(cTagICMS, "pMVAST") )
            nPREDBCST:= Val( XmlNode(cTagICMS, "pRedBCST") )
            nPICMSST := Val( XmlNode(cTagICMS, "pICMSST") )
            nVICMSST := Val( XmlNode(cTagICMS, "vICMSST") )
            
            cTagIPI := XmlNode(cTagDetItemX, "IPI")            
            nPIPI    := Val( XmlNode(cTagIPI, "pIPI") )
            nVIPI    := Val( XmlNode(cTagIPI, "vIPI") )
            
            cTagPIS  := XmlNode(cTagDetItemX, "PISAliq")
            IF Empty(cTagPIS)
               cTagPIS  := XmlNode(cTagDetItemX, "PISNT")
            ENDIF
            cCSTPIS  := XmlNode(cTagPIS, "CST")
            nVBCPIS  := Val( XmlNode(cTagPIS, "vBC") )
            nPPIS    := Val( XmlNode(cTagPIS, "pPIS") )
            nVPIS    := Val( XmlNode(cTagPIS, "vPIS") )         
                       
            cTagCOFINS := XmlNode(cTagDetItemX, "COFINSAliq")
            IF Empty(cTagCOFINS)
               cTagCOFINS := XmlNode(cTagDetItemX, "COFINSNT")
            ENDIF         
            cCSTCOFINS := XmlNode(cTagCOFINS, "CST")
            nVBCCOFINS := Val(XmlNode(cTagCOFINS, "vBC") )
            nPCOFINS   := Val( XmlNode(cTagCOFINS, "pCOFINS") )
            nVCOFINS   := Val( XmlNode(cTagCOFINS, "vCOFINS") )            

            /*
            IF cCFOP == '5102'
               IF Empty(nPICMS)
                  nPICMS := 19
               ELSEIF nPICMS = 12
                  nPICMS := 19
               ENDIF
            ENDIF
            */
            cCodMercad := ''
            eq->(ordSetFocus(8)) //cod_fiscal         
                                    
            IF lAchou := eq->(dbSeek(cEAN))
               cCodMercad := eq->cod_mercad            
            ELSEIF Len(cEAN) == 12 .AND. !lAchou
               //Procurar 2 vezes               
               IF SubStr(cEANZero,1,1) == '0'                  
                  IF eq->(dbSeek('0'+cEAN))
                     cCodMercad := eq->cod_mercad                                 
                  ENDIF
               ENDIF
            ELSE   
               IF lAchou := tp54e->(dbSeek(cEAN))
                  cCodMercad := tp54e->cod_mercad
               ELSEIF Len(cEAN) == 12 .AND. !lAchou
                  //Procurar 2 vezes               
                  IF SubStr(cEANZero,1,1) == '0'                     
                     IF tp54e->(dbSeek('0'+cEAN))
                        cCodMercad := tp54e->cod_mercad                                 
                     ENDIF
                  ENDIF
               ENDIF             
            ENDIF
                                   
            incluir('itens')
            itens->ticket     := cTicket
            itens->nfce       := StrZero(Val(cNF),9)
            itens->serie      := cSerie
            itens->dia        := dhemi
            itens->idcliente  := "000000"
            itens->cfop       := cCFOP
            itens->gtin       := cEAN
            itens->cprod      := cCodMercad //cCProd
            itens->xprod      := cXPROD
            itens->ucom       := cUCOM
            itens->qcom       := nQCom
            itens->VUnCom     := nVUnCom
            itens->ncm        := cNCM
            itens->cest       := cCEST
            itens->cst        := cOrig+cCST
            itens->vdesc      := nVDesc
            itens->picms      := nPICMS
            itens->vbc        := nVBC 
            itens->vicms      := nVICMS
            itens->cstpis     := cCSTPIS
            itens->ppis       := nPPIS
            itens->vbcpis     := nVBCPIS
            itens->vpis       := nVPIS
            itens->cstcofins  := cCSTCOFINS
            itens->pcofins    := nPCOFINS
            itens->vbccofins  := nVBCCOFINS
            itens->vcofins    := nVCOFINS
            itens->cean       := cEAN

         NEXT
      ENDIF      
      
   ENDIF
   
Next
Saudações,
Itamar M. Lins Jr.

Converter XML para DBF

Enviado: 16 Nov 2024 10:26
por clodoaldomonteiro
Já ha umas duas semanas estudando e vendo a melhor forma de converter um XML de 50MB para DBF me deparei com esse post do @Rochinha e resolvi reacender ele contribuindo e questionando algumas coisas, a fim de aprendermos mais.

Uma coisa q me deparei e fez com que repensasse a maneira de como pegar o valor das Chaves Nodes, foi a questão do método :selectSingleNode() tornar lento as operações com arquivos grandes, e aqui o Rochinha mostrou-me como usar o método :getElementsByTagName().

Como o método será usando muitas vezes, tive q pensar numa função simples para retornar o :Text do :Item(n), facilitando assim a vida do programador.

Código: Selecionar todos

XML:
<?xml version="1.0" encoding="utf-8"?>
<!--Arquivo XML para o SAGRES 2024 -->
<!--SIMPLES - Informatica e Consultoria Ltda -->
<!--www.simplesinformatica.com (86) 3223-0653 -->
<!--Sistema: SCP21H-Sistema de Contabilidade Publica -->
<!--Data do Sistema..: 12/11/2024 -  -->
<!--Versao do Sistema: 21.35.04 -->
<!--Versao do DB.....: 21.125 -->
<!--Pasta de Dados...: C:\SimplesInfo\Scp21H\DB2024\A2024_PMUN_PM_UNIAO\ -->
<!--XML Criado em....: 12/11/2024, 11:30:34 -->
<!--CNPJ Autorizado..: 06.553.606/0001-30 -->
<!--Emp. Autorizada..: PREFEITURA MUNICIPAL DE UNIAO -->
<!--Contador respons.: xxx -->
<!--Usuario Sistema..: CLODOALDO MONTEIRO & CONSULTORIA -->
<!--IP da maquina....: 10.211.55.8 -->
<!--Nome Maquina Rede: CLODOALDOSM9F4E -->
<!--Usuario Windows..: clodoaldosm -->

<lan:LancamentosContabeis xmlns:lan="http://www.tce.pi.gov.br/sagres2024/xml/LancamentosContabeis" xmlns:esp="http://www.tce.pi.gov.br/sagres2024/xml/especificos" xmlns:cc="http://www.tce.pi.gov.br/sagres2024/xml/contasCorrentes" xmlns:gen="http://www.tce.pi.gov.br/sagres2024/xml/genericos" xmlns:tab="http://www.tce.pi.gov.br/sagres2024/xml/tabelasInternas" xmlns:aux="http://www.tce.pi.gov.br/sagres2024/xml/cadastrosAuxiliares">

<!--PRESTACAO DE CONTAS =================================================================-->
   <lan:PrestacaoContas>
      <aux:codigoUnidGestora>201999</aux:codigoUnidGestora>
      <aux:nomeUnidGestora>PREFEITURA MUNICIPAL DE UNIAO</aux:nomeUnidGestora>
      <aux:cpfContador>00000000</aux:cpfContador>
      <aux:cpfGestor>00000000000</aux:cpfGestor>
      <aux:anoReferencia>2024</aux:anoReferencia>
      <aux:mesReferencia>01</aux:mesReferencia>
      <aux:versaoXml>1</aux:versaoXml>
      <aux:diaInicPresContas>01</aux:diaInicPresContas>
      <aux:diaFinaPresContas>31</aux:diaFinaPresContas>
   </lan:PrestacaoContas>
...
...
Function Main()
...
...
         objXml := TOLEAUTO():New( "Microsoft.XMLDOM" )
         objXml:async := .F.
         objXml:validateOnParse := .F.

         If objXml:load(mArq_) == .F.
            MsgError("Erro ao carregar o arquivo XML.")
            Break
         Endif

         nodes          := objXml:getElementsByTagName("lan:PrestacaoContas")
         nodePrestConta := nodes:item(0)
         
         mCodigoUnidGestora := xmlGetTextNode(nodePrestConta, "aux:codigoUnidGestora")
...
...
Return

   //Retorna valor de :Text de um :Item Node.
Function xmlGetTextNode(oXml, cNodeName)
   Local oNodes, oNode, r := ''

   // Verifica se o XML é válido
   IF Empty(oXml)
      Return r
   ENDIF

   // Busca os nós pelo nome
   oNodes := oXml:getElementsByTagName(cNodeName)

   // Verifica se encontrou ao menos um nó
   IF oNodes:length > 0
      oNode := oNodes:Item(0)
      IF !Empty(oNode)
         r := oNode:text
      ENDIF
   ENDIF

   // Retorna o valor ou Empty se não encontrado e garantindo q ainda assim é o Text.
   Return r
Abraços.

Converter XML para DBF

Enviado: 25 Nov 2024 02:12
por rochinha
Amiguinhos,

clodoaldomonteiro maravilha.

As vezes procuro uma solução aqui e ali e acabo encontrando uma dica ou auxilio que eu mesmo dei e não lembrava. Mas muitas vezes as dicas de colegas aqui me salvaram a pele.