Code: Select all
#require "hbmxml.hbc"
#include "hmg.ch"
Function Main
DBCREATE( 'invoice.dbf', { { "uid", "C", 40, 0 },;
{ "IssuerVatN" , "C", 9, 0 },;
{ "CountVatN" , "C", 9, 0 },;
{ "issueDate", "D", 8, 0 },;
{ "totNetVal", "N", 10, 2 } } )
DBCREATE( 'invoiceDetails.dbf', { { "uid", "C", 40, 0 },;
{ "LineNumber" , "N", 5, 0 },;
{ "NetValue", "N", 10, 2 } } )
DEFINE WINDOW Form_1 AT 0 , 0 WIDTH 300 HEIGHT 100 TITLE "HMG" MAIN ON INIT Start()
END WINDOW
CENTER WINDOW Form_1
ACTIVATE WINDOW Form_1
***********************************
Function Start()
Local cXmlFile := GetFile( {{'XML File', '*.xml'}}, 'Select XML', hb_CWD(), .F. , .T. )
IF EMPTY( cXmlFile )
RETURN Nil
ENDIF
SELECT 1
USE invoice
ZAP
SELECT 2
USE invoiceDetails
ZAP
WAIT WINDOW "Processing ..." NOWAIT
hb_XMLParser( hb_MemoRead ( cXmlFile ), .T., { | aRowXML | Parser_Request ( aRowXML ) } )
WAIT CLEAR
MsgInfo ( "Done" )
Return Nil
*******************************************************
Function Parser_Request ( aXmlOneRow )
Local cPath, cKey, xValue, hAttrib, xAttribValue
cPath := aXmlOneRow [ 1 ]
cKey := aXmlOneRow [ 2 ]
xValue := aXmlOneRow [ 3 ]
hAttrib := aXmlOneRow [ 4 ]
****** DO CASE for the Request.xml file structure ********
DO CASE
CASE cKey == "uid" .AND. cPath == "RequestedDoc/invoicesDoc/invoice"
SELECT invoice
APPEND BLANK
REPLACE invoice->uid WITH xValue
CASE cKey == "vatNumber" .AND. cPath == "RequestedDoc/invoicesDoc/invoice/issuer"
REPLACE invoice->IssuerVatN WITH xValue
CASE cKey == "vatNumber" .AND. cPath == "RequestedDoc/invoicesDoc/invoice/counterpart"
REPLACE invoice->CountVatN WITH xValue
CASE cKey == "issueDate" .AND. cPath == "RequestedDoc/invoicesDoc/invoice/invoiceHeader"
REPLACE invoice->issueDate WITH hb_CToD( xValue, "YYYY-MM-DD" )
CASE cKey == "lineNumber" .AND. cPath == "RequestedDoc/invoicesDoc/invoice/invoiceDetails"
SELECT invoiceDetails
APPEND BLANK
REPLACE invoiceDetails->uid WITH invoice->uid
REPLACE invoiceDetails->lineNumber WITH Val ( xValue )
CASE cKey == "netValue" .AND. cPath == "RequestedDoc/invoicesDoc/invoice/invoiceDetails"
REPLACE invoiceDetails->netValue WITH Val ( xValue )
CASE cKey == "totalNetValue" .AND. cPath == "RequestedDoc/invoicesDoc/invoice/invoiceSummary"
SELECT invoice
REPLACE invoice->totNetVal WITH Val ( xValue )
END CASE
Return
*****************************************************************************
STATIC FUNCTION hb_XMLParser( cXML, lOmitHeader, xFunction )
LOCAL pXML
Default lOmitHeader := .T.
IF hb_StrIsUtf8 ( cXML )
cXML := hb_utf8ToStr( cXML )
ENDIF
pXML := mxmlLoadString( NIL, cXML, MXML_OPAQUE_CALLBACK )
IF !Empty( pXML )
IF lOmitHeader
hb_XMLParser_getnodes( mxmlGetFirstChild( pXML ), xFunction )
ELSE
hb_XMLParser_getnodes( pXML, xFunction )
ENDIF
mxmlDelete( pXML )
ENDIF
RETURN
*****************************************************************************
STATIC FUNCTION hb_XMLParser_getnodes( pNode, xFunction )
LOCAL cKey, pChild, xResult, xValue, cPrevKey, hAttrib, pParrentNode, cPath
DO WHILE !Empty( pNode )
IF mxmlGetType( pNode ) == MXML_ELEMENT
cKey := mxmlGetElement( pNode )
pChild := mxmlGetFirstChild( pNode )
IF hb_mxmlGetAttrsCount ( pNode ) > 0 .AND. !Empty( pChild ) .AND. ( mxmlGetOpaque( pNode ) = CRLF .OR. Empty ( mxmlGetOpaque( pNode ) ) ) //Support nodes with child node and attribute(s) and no value
cPath := ""
pParrentNode := mxmlGetParent( pNode )
IF Left ( cKey, 8 ) == "![CDATA["
xValue := hb_StrShrink ( mxmlGetCDATA ( pNode ), 2 )
cKey := mxmlGetElement( mxmlGetParent( pNode ) )
pParrentNode := mxmlGetParent ( mxmlGetParent( pNode ) )
ENDIF
DO WHILE !EMPTY ( pParrentNode )
cPrevkey := mxmlGetElement( pParrentNode )
IF Left ( cPrevkey, 4 ) <> "?xml"
cPath := cPrevkey + IF( !Empty( cPath ), "/", "") + cPath
ENDIF
pParrentNode := mxmlGetParent( pParrentNode )
ENDDO
hAttrib := hb_mxmlGetAttrs( pNode )
IF HB_ISEVALITEM( xFunction )
Eval( xFunction, { cPath, cKey, Nil, hAttrib } )
ENDIF
ENDIF
xValue := hb_XMLParser_getnodes( pChild, xFunction )
IF xValue == NIL
xValue := mxmlGetOpaque( pNode )
IF !(xValue == CRLF)
cPath := ""
pParrentNode := mxmlGetParent( pNode )
IF Left ( cKey, 8 ) == "![CDATA["
xValue := hb_StrShrink ( mxmlGetCDATA ( pNode ), 2 )
cKey := mxmlGetElement( mxmlGetParent( pNode ) )
pParrentNode := mxmlGetParent ( mxmlGetParent( pNode ) )
ENDIF
DO WHILE !EMPTY ( pParrentNode )
cPrevkey := mxmlGetElement( pParrentNode )
IF Left ( cPrevkey, 4 ) <> "?xml"
cPath := cPrevkey + IF( !Empty( cPath ), "/", "") + cPath
ENDIF
pParrentNode := mxmlGetParent( pParrentNode )
ENDDO
hAttrib := hb_mxmlGetAttrs( pNode )
IF HB_ISEVALITEM( xFunction )
Eval( xFunction, { cPath, cKey, xValue, hAttrib } )
ENDIF
xResult := { cPath, cKey, xValue, hAttrib }
ENDIF
ENDIF
ENDIF
pNode := mxmlGetNextSibling( pNode )
ENDDO
RETURN xResult