Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML format

This forum is for eXpress++ general support.
Message
Author
Diego Euri Almanzar
Posts: 155
Joined: Thu Nov 05, 2020 10:51 am
Location: DOMINICAN REPUBLIC

Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML format

#1 Post by Diego Euri Almanzar »

I am a beginner in matters of the Web or Internet. But, I have to prepare myself, because the Government of the country where I live, will implement Electronic Invoicing, and I have started the certification. I haven't had much time to study the reports that the Tax office has sent me to start the Electronic Invoicing certification. However, despite my little experience, I notice that it is basically about sending and receiving information in JSON and XML format.

Where can I find examples of Xbase++, or Express++, codes that help me understand how to send and receive information on the Internet, or on the Web, in JSON and XML format?

Best regards.

User avatar
PedroAlex
Posts: 229
Joined: Tue Feb 09, 2010 3:06 am

Re: Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML fo

#2 Post by PedroAlex »

Hi Diego,
What country are you from?

The first step is being able to use XML!
You can start by analyzing the eXpress examples "\EXP20\Samples\Xml"

What version of Alaska and eXpress do you have?
Pedro Alexandre

User avatar
Tom
Posts: 1165
Joined: Thu Jan 28, 2010 12:59 am
Location: Berlin, Germany

Re: Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML fo

#3 Post by Tom »

You may also take a look at the "simple xml parser" coming with the Xbase++-samples. Also take a look at functions like Json2Var() and Xml2Var().

If you receive JSON or XML data from a REST-service, in most of the cases, the data acquired comes in a var which represents the XML or JSON contens (i.E. the response var itself). Both formats are sort of hierarchical multidimensional arrays, carrying both, the data and the data description. It's a little tricky to get special data from there - this can be done with simple text operations or with very complex recursive functions. It depends on the data and your needs.
Best regards,
Tom

"Did I offend you?"
"No."
"Okay, give me a second chance."

Diego Euri Almanzar
Posts: 155
Joined: Thu Nov 05, 2020 10:51 am
Location: DOMINICAN REPUBLIC

Re: Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML fo

#4 Post by Diego Euri Almanzar »

Hello, PedroAlex

I am from the Dominican Republic.

The version of Alaska and Express that I use is the most current, I use version 2.0 Both bought last year.

Is there an example where one can see or read the codes, which sentence is used to connect to a Web server, to send XML documents, or JSON?

Forgive my ignorance, but I'm new to this.

Diego Euri Almanzar
Posts: 155
Joined: Thu Nov 05, 2020 10:51 am
Location: DOMINICAN REPUBLIC

Re: Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML fo

#5 Post by Diego Euri Almanzar »

Hello Tom

I understand perfectly, thank you. Excuse my ignorance, I'm new to this. Apart from your valuable information, I would like to see some source code, to know the connection statement, to a Web server, that is needed to send or receive JSON, or XML data. Can you provide me with an example of source code, or does Express have that example in a folder?

User avatar
PedroAlex
Posts: 229
Joined: Tue Feb 09, 2010 3:06 am

Re: Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML fo

#6 Post by PedroAlex »

Diego,

Here is a small sample of a SOAP request with XML inline.

Code: Select all

//============================================================================
Function Teste_HTTP()
LOCAL soapRequest
LOCAL oHC
LOCAL cResult

  // Create the SOAP request message
  TEXT INTO soapRequest WRAP
  <?xml version="1.0" encoding="UTF-8"?>
  <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:ec.europa.eu:taxud:vies:services:checkVat:types">
   <SOAP-ENV:Body>
    <ns1:checkVat>
     <ns1:countryCode>DE</ns1:countryCode>
     <ns1:vatNumber>100</ns1:vatNumber>
    </ns1:checkVat>
   </SOAP-ENV:Body>
  </SOAP-ENV:Envelope>
  ENDTEXT

  msgBox(soapRequest)



  // Process the SOAP request
  //oHC := HttpClient():new( "http://ec.europa.eu/taxation_customs/vies/services/checkVatService" )
  oHC := HttpClient():new( "http://ec.europa.eu/taxation_customs/vies/checkVatTestService.wsdl" )
  oHC:setAcceptType( "text/xml" )
  oHC:setAcceptCharSet( "utf-8" )
  oHC:httpRequest:setHeader( "SOAPAction", "urn:checkVatService" )
  oHC:httpRequest:setMethod( "POST" )
  oHC:httpRequest:setContent( soapRequest )
  cResult := oHC:send()
  //? "Response returned for SOAP request:"
  msgBox( cResult, 'Result' )



Return NIL

Pedro Alexandre

bobvolz
Posts: 114
Joined: Sun Jan 31, 2010 11:25 am

Re: Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML fo

#7 Post by bobvolz »

Hi Diego;
Here is a snippet from my code that does a Vehicle ID lookup on a Vin Decoder website using XML.
I pass it a record object from several of my other functions.
I create and post an xml request string and DataOne returns an xml document.
The creation of the xml post string is simple code creating a text body (cBody). I add a CRLF after
each line to make it more readable during debugging.
You can use TEXT/ENDTEXT probably as well but I like the flexibility to access and insert vars in the creation of
the document.
I then use xb2net functions to create and post this string but I understand standard xBase++ can now do this as well.
I then use Rogers DC_XML functions and methods to parse the returned xml document.
DC_XML2OBJECTTREE(cString) creates an object that can be parsed using findnode,attr, and content methods.
It's great stuff. You will probably want to put a lot of validation in your code to test the valtypes of each returned
value to check to see if it is an object and if the content of that object is a character string. When necessary,
numeric data should be created using the val(cVal) function to match your database structure.

The code is below. Let me know if you have any questions.

*-------------------function to Retrieve Decoded Vin from DataOne for Credit App system ----------------------*

function vindecoderCA(oAceVehic) /// oAceVehic is a record object being passed from the calling function.
local GETLIST:={}, GETOPTIONS, oHttp,oResp,cXml,cBody:='',oForm ,xStatus,oRootnode,oTrim ,bPreError,oError
LOCAL oDecode,oQuery,oResponse,oMarket,oCommon,oBasic,oYear,oMake,oModel,oDoors,oDrive,oEngine,oEngines,;
oCylinders,oDisplace,oTrans,oTransmission,oType,oGears,oValue,cValue:='' , oStyle, aSpecs ,oSpecification
LOCAL oInstalledEquip,oOptionalEquip,aCategory:={},cCatname:='',cComment:='',aEquipment:={},i,j,cEquipname,cXmlData:=''

DCGETOPTIONS SAYWIDTH 0 SAYFONT '10.Courier New' GETFONT '10.Courier New' autoresize

/// if vin is empty- ask for it.
IF EMPTY(oAceVehic:Vin)
@ 10,0 DCSAY 'Enter Vin to Decode' get oAceVehic:Vin VALID{|| CHECKDIGIT(oAceVehic:Vin)}
DCREAD GUI TO XSTATUS ENTEREXIT BUTTONS 2 TITLE 'Vin Decoder'
endif
/// open VINDECODES DBF
IF UseDB({'VINDECODES'})
VINDECODES->(DBGOTOP())
ELSE
DC_WINALERT('Decoder file not available')
RETURN NIL
ENDIF
/// VALIDATE FOR A VALID VEHICLE ID
IF !CHECKDIGIT(oAceVehic:Vin)
DC_WINALERT('This is NOT a valid Vin!')
RETURN NIL
ENDIF

/// CREATE xml string - simply keep adding tags to cBody to construct the document. CRLF is a Carriage Return Line Feed that makes it easier to read.
/// this xml document conforms to what DataOne wants as an XML request.

SELECT VINDECODES
IF !VINDECODES->(DBSEEK(oAceVehic:Vin))
cBody:=cBody+'<?xml version="1.0" encoding="UTF-8"?>'+CRLF
cBody:=cBody+'<decoder_query>'+CRLF
cBody:=cBody+'<decoder_settings>'+CRLF
cBody:=cBody+'<display>full</display>'+CRLF
cBody:=cBody+'<styles>on</styles>'+CRLF
cBody:=cBody+'<style_data_packs>'+CRLF
cBody:=cBody+'<basic_data>on</basic_data>'+CRLF
cBody:=cBody+'<pricing>off</pricing>'+CRLF
cBody:=cBody+'<engines>on</engines>'+CRLF
cBody:=cBody+'<transmissions>on</transmissions>'+CRLF
cBody:=cBody+'<specifications>on</specifications>'+CRLF
cBody:=cBody+'<installed_equipment>on</installed_equipment>'+CRLF
cBody:=cBody+'<optional_equipment>on</optional_equipment>'+CRLF
cBody:=cBody+'<generic_optional_equipment>on</generic_optional_equipment>'+CRLF
cBody:=cBody+'<colors>on</colors>'+CRLF
cBody:=cBody+'<warranties>off</warranties>'+CRLF
cBody:=cBody+'<fuel_efficiency>off</fuel_efficiency>'+CRLF
cBody:=cBody+'<green_scores>off</green_scores>'+CRLF
cBody:=cBody+'<crash_test>off</crash_test>'+CRLF
cBody:=cBody+'</style_data_packs>'+CRLF
cBody:=cBody+'<common_data>on</common_data>'+CRLF
cBody:=cBody+'<common_data_packs>'+CRLF
cBody:=cBody+'<basic_data>on</basic_data>'+CRLF
cBody:=cBody+'<pricing>off</pricing>'+CRLF
cBody:=cBody+'<engines>on</engines>'+CRLF
cBody:=cBody+'<transmissions>on</transmissions>'+CRLF
cBody:=cBody+'<specifications>on</specifications>'+CRLF
cBody:=cBody+'<installed_equipment>on</installed_equipment>'+CRLF
cBody:=cBody+'<generic_optional_equipment>on</generic_optional_equipment>'+CRLF
cBody:=cBody+'</common_data_packs>'+CRLF
cBody:=cBody+'</decoder_settings>'+CRLF
cBody:=cBody+'<query_requests>'+ CRLF
cBody:=cBody+'<query_request identifier="'+oAceVehic:Vin+'">'+CRLF
cBody:=cBody+'<vin>'+oAceVehic:Vin+'</vin>'+CRLF
cBody:=cBody+'</query_request>'+CRLF
cBody:=cBody+'</query_requests>'+CRLF
cBody:=cBody+'</decoder_query>'+CRLF

///post to dataone
/// THESE ARE xB2Net functions

oHttp := xbHTTPClient():new()
oForm := xbForm():new()
oForm:SetVar("client_id", "xxxx")
oForm:SetVar("authorization_code", "xxxxxxxxxxxxxxxxxxxxxxxxxxxx ")
oForm:SetVar("decoder_query",cBody)
oResp := oHttp:Execute("https://api.dataonesoftware.com/webserv ... OST",oForm)

// if it is empty
if oResp == NIL
MsgBox("Error:" + str(oHttp:ErrorCode) + chr(10) + oHttp:ErrorMessage)
RETURN NIL
endif

SELECT VINDECODES /// ADD TO FILE FOR FUTURE USE
IF VINDECODES->(DC_ADDREC())
REPLACE VINDECODES->VIN WITH oAceVehic:Vin
REPLACE VINDECODES->PULLDATE WITH DATE()
REPLACE VINDECODES->XMLDATA WITH alltrim(oResp:content)
ENDIF

cXmlData:=alltrim(oResp:content) /// CONVERT TO STRING
oRootNode := DC_Xml2ObjectTree(cXmlData) /// AND PARSE
IF !valtype(oRootNode)=='O'
DC_WinAlert('Could not open file. Invalid Data Return from Vin Decoder ')
RETURN FALSE
ENDIF

ELSE /// IF IT IS FOUND IN VINDECODES
cXmlData := ALLTRIM(VINDECODES->XMLDATA) ///LOAD STRING
/// parse the string using Roger Donnay's XML function
oRootnode:= DC_Xml2ObjectTree(cXMLDATA) //PARSE
ENDIF

VINDECODES->(DBCLOSEAREA()) /// CLOSE VINDECODES FILE

/// POST INTERIM ERROR HANDLER
bPreError := ErrorBlock( {|oError| _vindecodeErrorBlock(oError)})

BEGIN SEQUENCE


// if oRootnode is not a valid object RETURN
IF !VALTYPE(oRootnode)=='O'
DC_WINALERT('Vin Decode not available for this vehicle')
RETURN NIL
ENDIF

/// NOW TEST FOR OTHER NODES
oDecode:=oRootnode:findnode('decoded_data')
IF !valtype(oDecode) = 'O'
DC_WINALERT('No Decoder Info available on this vehicle.')
RETURN NIL
endif

oQuery:=oDecode:findnode('query_responses')
IF !valtype(oQuery) = 'O'
DC_WINALERT('No Decoder Info available on this vehicle.')
RETURN NIL
endif

oResponse:=oQuery:findnode('query_response')
IF !valtype(oResponse) = 'O'
DC_WINALERT('No Decoder Info available on this vehicle.')
RETURN NIL
endif

oMarket:=oResponse:findnode('us_market_data')
IF !valtype(oMarket) = 'O'
DC_WINALERT('No Decoder Info available on this vehicle.')
RETURN NIL
endif

oCommon:=oMarket:findnode('us_styles')
IF !valtype(oCommon) = 'O'
DC_WINALERT('No Decoder Info available on this vehicle.')
RETURN NIL
endif

oStyle:=oCommon:findnode('style')
IF !VALTYPE(oStyle) == 'O'
DC_WINALERT('Vin Decode not available for this vehicle')
RETURN NIL
ENDIF

oBasic:=oStyle:findnode('basic_data')
IF !VALTYPE(oBasic) == 'O'
DC_WINALERT('Vin Decode not available for this vehicle')
RETURN NIL
ENDIF


/// POPULATE oAceVehic with data extracted from above
oYear:=oBasic:findnode('year')
oAceVehic:year:=oYear:content

cComment:=cComment+oYear:content +CRLF
oMake:=oBasic:findnode('make')
oAceVehic:make:=oMake:content

oModel:=oBasic:findnode('model')
oAceVehic:model:=oModel:content

END SEQUENCE

ErrorBlock(bPreError)

return oAceVehic

Diego Euri Almanzar
Posts: 155
Joined: Thu Nov 05, 2020 10:51 am
Location: DOMINICAN REPUBLIC

Re: Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML fo

#8 Post by Diego Euri Almanzar »

Hi Pedro Alex, bobvolz

I knew absolutely nothing about this subject. And, in a few hours, I'll become an expert in sending an xml, and I'll get a response from a web server. I am very grateful. Your examples and explanations are excellent.

I hope not to abuse expanding the subject more. Since I don't have the XB2NET library, I'll use HTTPCLIENT from Alaska Xbase++

Best regards

reganc
Posts: 257
Joined: Thu Jan 28, 2010 3:08 am
Location: Hersham, Surrey, UK
Contact:

Re: Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML fo

#9 Post by reganc »

I'll quickly throw this in as a possibility.

We use the Chilkat libraries quite extensively for XML, JSON, HTTP and REST as they are very good.

The XML and JSON parts of the library appear to be free. And they make the creation and usage of XML and JSON easy.
Regan Cawkwell
Real Business Applications Ltd
http://www.rbauk.com

Diego Euri Almanzar
Posts: 155
Joined: Thu Nov 05, 2020 10:51 am
Location: DOMINICAN REPUBLIC

Re: Examples in Xbase++ code, or Express++, to help me understand how to send and receive information in JSON and XML fo

#10 Post by Diego Euri Almanzar »

Hello, Reganc

I think a library dedicated to these purposes is great, because although the subject of JSON and XML seems easy, these times are complicated, and time cannot be wasted.

However, as I have been investigating, the library is not for XBASE++, it is for Visual Fox Pro.

Will there be a version for Xbase++?

Post Reply