sábado, febrero 04, 2012

VFP: Un parser para JSON


Para los que, como yo, nunca hayan escuchado hablar de JSON, se trata de una tecnologia ampliamente usada en la web para el intercambio de datos entre sistemas desconectados. Básicamente es lenguaje muy simple que permite definir objetos y su contenido. Los parsers JSON hacen dos cosas:

a) Toman una referencia a un objeto (normalmente JavaScript) y genera una representación JSON en forma de string
b) Toman un string JSON y devuelve el objeto original

A pesar que en el sitio JSON.org se pueden encontrar dos parsers JSON para VFP, decidi hacer mi propio parser usando solo código VFP y, de paso, incluyendo un par de mejoras al estilo fox.

La mejor de estas adiciones es lo que llame "schema". Un schema es basicamente una forma de definir uns estructura de datos reutilizable, al estilo de la construcción STRUCT en C# (pero sin la posibilidad de incluir metodos).

Por ejemplo, para definir el schema "User":

JSON.declareSchema("User","{loginName:string, fullName: string, profileId: numeric, active: boolean}")

Luego, cuando queremos trabajar con un objeto que represente un usuario, solo hacemos:

oUser = JSONObject("schema:User")
oUser.loginName = 'vespina'
oUser.fullName = 'Victor Espina'
oUser.profileId = 25
oUser.active = .T.


Supongamos ahora que queremos almacenar los datos del usuario que modifico un registro. Con JSON podriamos hacerlo asi:

SELECT clientes
REPLACE rowLastUpd WITH DATETIME(),;
        rowUpdBy   WITH oUser.ToJSON()

Luego, cuando queramos mostrar quien modifico el registro, hacemos:

oUser = JSONObject(clientes.rowUpdBy)
MESSAGEBOX("Este registro fue modificado por " + oUser.fullName)


Otro uso muy comun de JSON es crear objetos sobre la marcha de forma sencilla:

oPoint = JSONObject("{x:10, y:20}")
?oPoint.x --> 10


Como ven, las posibilidades son muchas. En la documentacion de la libreria hay multitud de ejemplos de todo lo que se puede hacer con ella.


Descargar qdfoxJSON (version 1.2 del 9 Feb de 2012).

5 comentarios:

meforero or dijo...

Ingeniero Victor Espina

Buenas tardes:

Me toca usar un servicio jason por URL internet, muy amables me han
enviado ejemplos, pero el servicio me exige metodo post, tengo el
siguiente ejemplo pero no funciona:

LOCAL loXMLHTTP as "MSXML2.XMLHTTP"

oHttp = Createobject("WinHttp.WinHttpRequest.5.1")
oHttp.Open("POST", "http://www.pegaleal1000.com/site/micuenta/wsmbe.php",.F.)
oHttp.Send()

loXmlHttp = CREATEOBJECT("MSXML2.XMLHTTP")
WITH loXmlHttp
.open("POST", "http://www.pegaleal1000.com/site/micuenta/wsmbe.php")
.Send()
jsonString= .responseText
jsonstring = LEFT(jsonstring,AT('}'+CHR(13),jsonstring))

ENDWITH

Me podria brindar alguna ayuda gracias.

m dijo...
Este comentario ha sido eliminado por un administrador del blog.
Victor Espina dijo...

El enlace de descarga ha sido actualizado.

Henry l dijo...
Este comentario ha sido eliminado por el autor.
Henry l dijo...

Hola Victor
Gracias por tu tiempo
Tengo este codigo

SET PROCEDURE TO C:\WBSRVIPROV2\qdfoxJSON additive
JSONStart()
SET STEP ON
TEXT TO cadena ADDITIVE NOSHOW TEXTMERGE
{DocumentStatus:70,StatusDate:2020-02-12T14:52:13,CUFE:fa681c74576976b4a482579b551bec189e0aee5eda612a6070a49ec536313b51bb8abf652d60ba1cc5530c463a17599b,DocumentNumber:PRUE3981,CustomerParty:CARLOS ALEXANDER M,CustomerPartyID:1126xxxx,DIANErrors:[{Code:0000,Description:0},{Code:FAB10b,Description:El prefijo debe corresponder al prefijo autorizado en la resolución.},{Code:FAJ50,Description:El prefijo debe corresponder al código de la sucursal de este punto de facturación},{Code:FAB10a,Description:El prefijo de numeración no es igual al código de la sucursal correspondiente a este punto de facturación},{Code:AR-1,Description:Regla: 90, Rechazo: Documento procesado anteriormente.},{Code:AR-2,Description:Código: Validación contiene errores en campos mandatorios.}]}
ENDTEXT
JSON.declareSchema("User","{DocumentStatus:numeric,StatusDate:string,cufe:string,DocumentNumbe:string,CustomerParty:string,CustomerPartyID::string,DIANErrors:string}")
oUser = JSONObject("schema:User")
oData = JSON.Parse(cadena)
MESSAGEBOX('estado ..'+STR(oData.DocumentStatus),0)
MESSAGEBOX('Cufe ..'+STR(oData.cufe),0)
MESSAGEBOX('Fecha ..'+STR(oData.StatusDate),0)

El problema es que oData.cufe no trae el valor

Mil Gracias por tu ayuda