我电脑中收集的,也不知是哪位大侠的作品,不知对你有用否?
*
* VFP_Json.prg
*
function json_encode(xExpr)
if vartype(_json)<>'O'
public _json
_json = newobject('json')
endif
return _json.encode(@xExpr)
function json_decode(cJson)
local retval
if vartype(_json)<>'O'
public _json
_json = newobject('json')
endif
retval = _json.decode(cJson)
if not empty(_json.cError)
return null
endif
return retval
function json_getErrorMsg()
return _json.cError
function recordToJson
local nRecno,i,oObj, cRetVal
if alias()==''
return ''
endif
oObj = newObject('myObj')
for i=1 to fcount()
oObj.set(Field(i),eval(Field(i)))
next
cRetVal = json_encode(oObj)
if not empty(json_getErrorMsg())
cRetVal = 'ERROR:'+json_getErrorMsg()
endif
return cRetVal
function tableToJson
local nRecno,i,oObj, cRetVal,nRec
if alias()==''
return ''
endif
nRecno = recno()
nRec = 1
dimension aInfo[1]
scan
oObj = newObject('myObj')
for i=1 to fcount()
oObj.set(Field(i),eval(Field(i)))
next
dimension aInfo[nRec]
aInfo[nRec] = oObj
nRec = nRec+1
endscan
goto nRecno
cRetVal = json_encode(@aInfo)
if not empty(json_getErrorMsg())
cRetVal = 'ERROR:'+json_getErrorMsg()
endif
return cRetVal
define class json as custom
nPos=0
nLen=0
cJson=''
cError=''
function encode(xExpr)
local cTipo
if type('ALen(xExpr)')=='N'
cTipo = 'A'
Else
cTipo = VarType(xExpr)
Endif
Do Case
Case cTipo=='D'
return '"'+dtos(xExpr)+'"'
Case cTipo=='N'
return Transform(xExpr)
Case cTipo=='L'
return iif(xExpr,'true','false')
Case cTipo=='X'
return 'null'
Case cTipo=='C'
xExpr = allt(xExpr)
xExpr = StrTran(xExpr, '\', '\\' )
xExpr = StrTran(xExpr, '/', '\/' )
xExpr = StrTran(xExpr, Chr(9), '\t' )
xExpr = StrTran(xExpr, Chr(10), '\n' )
xExpr = StrTran(xExpr, Chr(13), '\r' )
xExpr = StrTran(xExpr, '"', '\"' )
return '"'+xExpr+'"'
case cTipo=='O'
local cProp, cJsonValue, cRetVal, aProp[1]
=AMembers(aProp,xExpr)
cRetVal = ''
for each cProp in aProp
if type('xExpr.'+cProp)=='U' or cProp=='CLASS'
loop
endif
if type( 'ALen(xExpr.'+cProp+')' ) == 'N'
Local i,nTotElem
cJsonValue = ''
nTotElem = Eval('ALen(xExpr.'+cProp+')')
For i=1 to nTotElem
cmd = 'cJsonValue=cJsonValue+","+ this.encode( xExpr.'+cProp+'[i])'
&cmd.
Next
cJsonValue = '[' + substr(cJsonValue,2) + ']'
else
cJsonValue = this.encode( evaluate( 'xExpr.'+cProp ) )
endif
if left(cProp,1)=='_'
cProp = substr(cProp,2)
endif
cRetVal = cRetVal + ',' + '"' + lower(cProp) + '":' + cJsonValue
next
return '{' + substr(cRetVal,2) + '}'
case cTipo=='A'
local valor, cRetVal
cRetVal = ''
for each valor in xExpr
cRetVal = cRetVal + ',' + this.encode( valor )
next
return '[' + substr(cRetVal,2) + ']'
endcase
return ''
function decode(cJson)
local retValue
cJson = StrTran(cJson,chr(9),'')
cJson = StrTran(cJson,chr(10),'')
cJson = StrTran(cJson,chr(13),'')
cJson = this.fixUnicode(cJson)
this.nPos = 1
this.cJson = cJson
this.nLen = len(cJson)
this.cError = ''
retValue = this.parsevalue()
if not empty(this.cError)
return null
endif
if this.getToken()<>null
this.setError('Junk at the end of JSON input')
return null
endif
return retValue
function parseValue()
local token
token = this.getToken()
if token==null
this.setError('Nothing to parse')
return null
endif
do case
case token=='"'
return this.parseString()
case isdigit(token) or token=='-'
return this.parseNumber()
case token=='n'
return this.expectedKeyword('null',null)
case token=='f'
return this.expectedKeyword('false',.f.)
case token=='t'
return this.expectedKeyword('true',.t.)
case token=='{'
return this.parseObject()
case token=='['
return this.parseArray()
otherwise
this.setError('Unexpected token')
endcase
return
function expectedKeyword(cWord,eValue)
for i=1 to len(cWord)
cChar = this.getChar()
if cChar <> substr(cWord,i,1)
this.setError("Expected keyword '" + cWord + "'")
return ''
endif
this.nPos = this.nPos + 1
next
return eValue
function parseObject()
local retval, cPropName, xValue
retval = createObject('myObj')
this.nPos = this.nPos + 1
if this.getToken()<>'}'
do while .t.
cPropName = this.parseString()
if not empty(this.cError)
return null
endif
if this.getToken()<>':'
this.setError("Expected ':' when parsing object")
return null
endif
this.nPos = this.nPos + 1
xValue = this.parseValue()
if not empty(this.cError)
return null
endif
retval.set(cPropName, xValue)
if this.getToken()<>','
exit
endif
this.nPos = this.nPos + 1
enddo
endif
if this.getToken()<>'}'
this.setError("Expected '}' at the end of object")
return null
endif
this.nPos = this.nPos + 1
return retval
function parseArray()
local retVal, xValue
retval = createObject('MyArray')
this.nPos = this.nPos + 1
if this.getToken() <> ']'
do while .t.
xValue = this.parseValue()
if not empty(this.cError)
return null
endif
retval.add( xValue )
if this.getToken()<>','
exit
endif
this.nPos = this.nPos + 1
enddo
if this.getToken() <> ']'
this.setError('Expected ] at the end of array')
return null
endif
endif
this.nPos = this.nPos + 1
return retval
function parseString()
local cRetVal, c
if this.getToken()<>'"'
this.setError('Expected "')
return ''
endif
this.nPos = this.nPos + 1
cRetVal = ''
do while .t.
c = this.getChar()
if c==''
return ''
endif
if c == '"'
this.nPos = this.nPos + 1
exit
endif
if c == '\'
this.nPos = this.nPos + 1
if (this.nPos>this.nLen)
this.setError('\\ at the end of input')
return ''
endif
c = this.getChar()
if c==''
return ''
endif
do case
case c=='"'
c='"'
case c=='\'
c='\'
case c=='/'
c='/'
case c=='b'
c=chr(8)
case c=='t'
c=chr(9)
case c=='n'
c=chr(10)
case c=='f'
c=chr(12)
case c=='r'
c=chr(13)
otherwise
this.setError('Invalid escape sequence in string literal')
return ''
endcase
endif
cRetVal = cRetVal + c
this.nPos = this.nPos + 1
enddo
return cRetVal
function parseNumber()
local nStartPos,c, isInt, cNumero
if not ( isdigit(this.getToken()) or this.getToken()=='-')
this.setError('Expected number literal')
return 0
endif
nStartPos = this.nPos
c = this.getChar()
if c == '-'
c = this.nextChar()
endif
if c == '0'
c = this.nextChar()
else
if isdigit(c)
c = this.nextChar()
do while isdigit(c)
c = this.nextChar()
enddo
else
this.setError('Expected digit when parsing number')
return 0
endif
endif
isInt = .t.
if c=='.'
c = this.nextChar()
if isdigit(c)
c = this.nextChar()
isInt = .f.
do while isDigit(c)
c = this.nextChar()
enddo
else
this.setError('Expected digit following dot comma')
return 0
endif
endif
define class myObj as custom
Hidden ;
ClassLibrary,Comment, ;
BaseClass,ControlCount, ;
Controls,Objects,Object,;
Height,HelpContextID,Left,Name, ;
Parent,ParentClass,Picture, ;
Tag,Top,WhatsThisHelpID,Width
function set(cPropName, xValue)
cPropName = '_'+cPropName
do case
case type('ALen(xValue)')=='N'
local nLen,cmd,i
this.addProperty(cPropName+'(1)')
nLen = alen(xValue)
cmd = 'Dimension This.'+cPropName+ ' [ '+Str(nLen,10,0)+']'
&cmd.
for i=1 to nLen
cmd = 'This.'+cPropName+ ' [ '+Str(i,10,0)+'] = xValue[i]'
&cmd.
next
case type('this.'+cPropName)=='U'
this.addProperty(cPropName,@xValue)
otherwise
local cmd
cmd = 'this.'+cPropName+'=xValue'
&cmd
endcase
return
procedure get (cPropName)
cPropName = '_'+cPropName
If type('this.'+cPropName)=='U'
return ''
Else
local cmd
cmd = 'return this.'+cPropName
&cmd
endif
return ''
enddefine
*
* test_vfp_json.prg
*
set proc to VFP_json additive
create cursor customers (id n(5), name c(50), lastname c(50), phone c(30))
insert into customers values (1,'Ignacio','Gutierrez','(653)534-8800')
insert into customers values (2,'Antonio','Esparza','(81)8347-1411')
insert into customers values (3,'David','Flores','(653)534-2755')
? 'Json Representing for each customer'
select customers
scan
? recordToJson()
endscan
?
?
? 'Now json represent of a whole table'
go top
? tableToJson()