一 创建用户对象sailjson
forward
global type sailjson from nonvisualobject
end type
type json_pair from structure within sailjson
end type
end forward
type json_pair from structure
string name
any value
end type
global type sailjson from nonvisualobject
end type
global sailjson sailjson
type variables
/*
Sailjson:from www.pblsoft.com
Please reserve this information
Version:2.1
Release date:2016-1-13
update:add root is array. getrootarray
Version:2.0
Release date:2016-1-1
*/
private:
json_pair pairs[]
string is_json
char ichars[]
long idx, imaxlen
treeview tree
integer objectpcxidx, arraypcxidx, itempcxidx
string is_ident
public:
boolean ignoreCase = false
integer ilevel
string pair_index
end variables
forward prototypes
public function string parse (string as_json)
public function integer getarray (string itemname, ref any va[])
public function boolean isarray (any value)
public function any getattribute (string itemname)
private function integer of_readobject (sailjson vjson, integer alevel)
private subroutine of_error (string msg)
private subroutine skipspc ()
private function long findpairindex (string as_name)
private function string of_getformat (sailjson ajson, string ident)
private function string mymid (character vchars[], long vstart, long vlen)
public subroutine buildtree (treeview atree, long handle, integer aobjectpcxidx, integer aarraypcxidx, integer aitempcxidx)
private subroutine of_buildtree (sailjson ajson, long handle)
public subroutine setattribute (string as_name, any aa_value)
public function any addarrayitem (string arrayname)
public function any addobject (string objname)
public function string getformatjson (string ident)
private function integer of_readarray (ref any varray, integer alevel)
private subroutine of_buildtreeofarray (any varray, long handle)
private function string of_getformatofarray (any varray, string ident)
public function integer getrootarray (ref any va[])
end prototypes
public function string parse (string as_json);json_pair pairsnull[]
pairs = pairsnull
is_json = as_json
ichars = as_json
imaxlen = len(as_json)
integer li_level = 0
idx = 0
skipspc()
if ichars[idx] = '{' then
of_readobject(this, li_level)
elseif ichars[idx] = '[' then
any la
of_readarray(la, li_level)
pairs[1].value = la
//pairs[1].name = "root"
this.pair_index += ";root=1"
end if
return ''
end function
public function integer getarray (string itemname, ref any va[]);any la
la = GetAttribute(itemname)
if isArray(la) then
va= la
return upperbound(va)
end if
return 0
end function
public function boolean isarray (any value);return classname(value)='any'
end function
public function any getattribute (string itemname);long index
if ignoreCase then
itemname = upper(itemname)
end if
index = findpairindex(itemname)
if index = 0 then
SignalError(42,"JSON.getAttribute: attribute "+string(itemname,"[general]")+" does not exists!")
//return "!ERROR!"
return ""
end if
return pairs[index].value
end function
private function integer of_readobject (sailjson vjson, integer alevel);//{....}
integer li_level , pairidx, arrayidx
string ls_name, ls_value
any la_value, la[], lanull[]
sailjson ljson
if ichars[idx] <> '{' then
return -1
end if
li_level = alevel + 1
vjson.ilevel = li_level
skipspc()
do while idx < imaxlen
//read key name, the first char is "
if ichars[idx] = '"' then
idx ++
ls_name = ''
ls_value = ''
do while ichars[idx] <> '"'
ls_name = ls_name + ichars[idx]
idx++
loop
skipspc()
if ichars[idx] <> ':' then
of_error("Error:Expect ':' but not found")
end if
skipspc()
choose case ichars[idx]
case '"'
//read string value
idx ++
do until ichars[idx] = '"'
if ichars[idx] = '\' then
ls_value = ls_value + ichars[idx+1]
idx = idx + 2
else
ls_value = ls_value + ichars[idx]
idx ++
end if
loop
la_value = ls_value
case '{'
//read object
ljson = create sailjson
of_readobject(ljson, li_level)
la_value = ljson
case '['
of_readarray(la_value, li_level)
case '0' to '9', '-'
do until ichars[idx] = ',' or ichars[idx] = '}'
ls_value = ls_value + ichars[idx]
idx ++
loop
idx --
la_value = dec(ls_value)
case 't'
if mymid(ichars, idx, 4) = 'true' then
idx += 3
else
of_error('Error:invalid key value!')
end if
la_value = true
case 'f'
if mymid(ichars, idx, 5) = 'false' then
idx += 4
else
of_error('Error:invalid key value!')
end if
la_value = false
case 'n'
if mymid(ichars, idx, 4) = 'null' then
idx += 3
else
of_error('Error:invalid key value!')
end if
setnull(la_value)
case else
of_error('Error:invalid key value!')
end choose
pairidx ++
vjson.pairs[pairidx].name = ls_name
vjson.pairs[pairidx].value = la_value
if ignoreCase then
ls_name = upper(ls_name)
end if
vjson.pair_index += ";"+ls_name+"="+string(pairidx)
skipspc()
if ichars[idx] = ',' then
//read next key and value
skipspc()
elseif ichars[idx] = '}' then
return 1
end if
else
of_error('Error:Expect key name with " but not found')
return -1
end if
loop
return 1
end function
private subroutine of_error (string msg);SignalError(1025, msg)
//"sailjson.getattribute: attribute "+string(itemname,"[general]")+" does not exists!")
end subroutine
private subroutine skipspc ();char c
IDX ++
c = ichars[idx]
do while c=' ' or c='~r' or c='~n' or c='~t' or c='~b' or c='~f'
idx ++
c = ichars[idx]
loop
end subroutine
private function long findpairindex (string as_name);long p1, p2, index
p1 = pos( pair_index, ';'+as_name + "=" )
if p1 < 1 then
return 0
end if
p1 += 2 + len(as_name)
p2 = pos(pair_index,';',p1)
if p2 < 1 then
p2 = len( pair_index ) + 1
end if
index = long( mid( pair_index, p1, p2 - p1 ) )
return index
end function
private function string of_getformat (sailjson ajson, string ident);string ls, ls1, ls_return, ls_ident, ls_rtn
integer li,lj, li_max, lj_max
any la, larray[]
if ident <> '' then
ls_ident = ident + is_ident
ls_rtn = '~r~n'
end if
li_max = upperbound(ajson.pairs)
for li = 1 to li_max
la = ajson.pairs[li].value
ls = '"'+ajson.pairs[li].name+'": '
if classname(la)='string' then
ls = ls + '"'+la+'"'
elseif classname(la)='decimal' then
ls = ls + string(la)
elseif classname(la)='boolean' then
if la = true then
ls = ls + 'true'
else
ls = ls + 'false'
end if
elseif isnull(classname(la)) then
ls = ls+'null'
elseif classname(la)='any' then
//ls = ls_names[li]
else
ls = ls + string(la)
end if
if classname(la) = 'sailjson' then
ls = ident + ls + '{'+ls_rtn
ls = ls + of_getformat(la, ls_ident)
ls = ls + ident + '}'
elseif classname(la)='any' then
ls = ident + ls + '['+ls_rtn
ls = ls + of_getformatofarray(la, ident)
ls = ls +ident + ']'
else
ls = ident + ls
end if
if li=li_max then
ls_return += ls + ''+ls_rtn
else
ls_return += ls + ','+ls_rtn
end if
next
return ls_return
end function
private function string mymid (character vchars[], long vstart, long vlen);string result
long vmax , i
vmax = upperbound(vchars)
if vstart > vmax then
vstart = vmax
end if
if vstart + vlen -1 > vmax then
vlen = vmax - vstart +1
end if
for i = vstart to vstart + vlen -1
result = result + vchars[i]
next
return result
end function
public subroutine buildtree (treeview atree, long handle, integer aobjectpcxidx, integer aarraypcxidx, integer aitempcxidx);tree = atree
objectpcxidx = aobjectpcxidx
arraypcxidx = aarraypcxidx
itempcxidx = aitempcxidx
of_buildtree(this, handle)
end subroutine
private subroutine of_buildtree (sailjson ajson, long handle);string ls
integer li,lj, h, pcx, h1
treeviewitem tvi
any la, larray[]
for li = 1 to upperbound(ajson.pairs)
pcx = itempcxidx
la = ajson.pairs[li].value
if classname(la)='string' then
ls = ajson.pairs[li].name + '="'+la+'"'
elseif classname(la)='decimal' then
ls = ajson.pairs[li].name + '='+string(la)
elseif classname(la)='boolean' then
ls = ajson.pairs[li].name + '='+string(la)
elseif classname(la)='any' then
ls = ajson.pairs[li].name+'['+string(upperbound(la))+']'
pcx = arraypcxidx
elseif isnull(classname(la)) then
ls = ajson.pairs[li].name+'=null'
else
ls = ajson.pairs[li].name
pcx = objectpcxidx
end if
tvi.label = ls
tvi.pictureindex = pcx
tvi.selectedpictureindex = pcx
h = tree.insertitemlast( handle, tvi)
if classname(la) = 'sailjson' then
of_buildtree(la, h)
elseif classname(la)='any' then
of_buildtreeofarray(la, h)
end if
next
end subroutine
public subroutine setattribute (string as_name, any aa_value);long index
index = findpairindex(as_name)
if index < 1 then
index = 1 + upperbound(pairs[])
json_pair pair
pairs[index] = pair
pairs[index].name = as_name
pair_index += ";"+as_name+"="+string(index)
end if
pairs[index].value = aa_value
end subroutine
public function any addarrayitem (string arrayname);sailjson ljson
any jsons[]
json_pair pair
integer index
ljson = create sailjson
index = findpairindex(arrayname)
if index < 1 then
index = 1 + upperbound(pairs[])
pairs[index] = pair
pairs[index].name = arrayname
jsons[1] = ljson
pair_index += ";"+arrayname+"="+string(index)
else
jsons = pairs[index].value
jsons[upperbound(jsons)+1] = ljson
end if
pairs[index].value = jsons
return ljson
end function
public function any addobject (string objname);sailjson ljson
json_pair pair
integer index
index = 1 + upperbound(pairs[])
pairs[index] = pair
pairs[index].name = objname
ljson = create sailjson
pairs[index].value = ljson
pair_index += ";"+objname+"="+string(index)
return ljson
end function
public function string getformatjson (string ident);string ls_return
is_ident = ident
ls_return = '{'
if is_ident <> '' then
ls_return = ls_return + '~r~n'
end if
ls_return = ls_return + of_getformat(this,is_ident) + '}'
return ls_return
end function
private function integer of_readarray (ref any varray, integer alevel);//[....]
integer li_level , pairidx, arrayidx
string ls_name, ls_value
any la_value, la[], lanull[]
sailjson ljson
arrayidx = 0
la=lanull
skipspc()
do until ichars[idx] = ']'
arrayidx ++
if ichars[idx] = '{' then
ljson = create sailjson
of_readobject(ljson, li_level)
la[arrayidx] = ljson
elseif ichars[idx] = '[' then
of_readarray(la_value, li_level)
la[arrayidx] = la_value
else
ls_value = ''
choose case ichars[idx]
case '"'
//read string value
idx ++
do until ichars[idx] = '"' or idx > imaxlen
if ichars[idx] = '\' then
ls_value = ls_value + ichars[idx+1]
idx = idx + 2
else
ls_value = ls_value + ichars[idx]
idx ++
end if
loop
la[arrayidx] = ls_value
case '0' to '9', '-'
do until ichars[idx] = ',' or ichars[idx] = ']' or idx > imaxlen
if (ichars[idx]>='0' and ichars[idx]<='9') &
or ichars[idx]='.' or ichars[idx]='-' then
ls_value = ls_value + ichars[idx]
idx ++
else
exit
end if
loop
idx --
la[arrayidx] = dec(ls_value)
case 't'
if mymid(ichars, idx, 4) = 'true' then
idx += 3
else
of_error('Error:invalid key value!')
end if
la[arrayidx] = true
case 'f'
if mymid(ichars, idx, 5) = 'false' then
idx += 4
else
of_error('Error:invalid key value!')
end if
la[arrayidx] = false
case 'n'
if mymid(ichars, idx, 4) = 'null' then
idx += 3
else
of_error('Error:invalid key value!')
end if
setnull(la[arrayidx])
case else
end choose
end if
skipspc()
if ichars[idx] = ',' then
skipspc()
end if
loop
varray = la
return arrayidx
end function
private subroutine of_buildtreeofarray (any varray, long handle);string ls
integer li,lj, h, pcx, h1
treeviewitem tvi
any la, larray[]
larray = varray
for li = 1 to upperbound(larray)
pcx = itempcxidx
la = larray[li]
if classname(la)='string' then
ls = '"'+la+'"'
elseif classname(la)='decimal' then
ls = string(la)
elseif classname(la)='boolean' then
ls = string(la)
elseif classname(la)='any' then
ls = '['+string(upperbound(la))+']'
pcx = arraypcxidx
elseif isnull(classname(la)) then
ls = 'null'
else
ls = 'item'+string(li)
pcx = objectpcxidx
end if
tvi.label = ls
tvi.pictureindex = pcx
tvi.selectedpictureindex = pcx
h = tree.insertitemlast( handle, tvi)
if classname(la) = 'sailjson' then
of_buildtree(la, h)
elseif classname(la)='any' then
of_buildtreeofarray( la, h)
end if
next
end subroutine
private function string of_getformatofarray (any varray, string ident);string ls, ls1, ls_return, ls_ident, ls_rtn
integer li,lj, li_max, lj_max
any la, larray[]
if ident <> '' then
ls_ident = ident + is_ident
ls_rtn = '~r~n'
end if
larray = varray
li_max = upperbound(larray)
for li = 1 to li_max
la = larray[li]
ls = ''
if classname(la)='string' then
ls = ls + '"'+la+'"'
elseif classname(la)='decimal' then
ls = ls + string(la)
elseif classname(la)='boolean' then
if la = true then
ls = ls + 'true'
else
ls = ls + 'false'
end if
elseif isnull(classname(la)) then
ls = ls+'null'
else
ls = ls + string(la)
end if
if classname(la) = 'sailjson' then
ls = ls_ident + ls + '{'+ls_rtn
ls = ls + of_getformat(la, ls_ident+is_ident)
ls = ls + ls_ident + '}'
elseif classname(la)='any' then
ls = ls_ident + ls + '['+ls_rtn
ls = ls + of_getformatofarray(la, ls_ident+is_ident)
ls = ls +ls_ident + ']'
else
ls = ls_ident + ls
end if
if li=li_max then
ls_return += ls + ''+ls_rtn
else
ls_return += ls + ','+ls_rtn
end if
next
return ls_return
end function
public function integer getrootarray (ref any va[]);return getarray('root', va)
end function
on sailjson.create
call super::create
TriggerEvent( this, "constructor" )
end on
on sailjson.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on
二 生成JSON格式数据
string ls_json
sailjson ljson,ljson1,ljson_data
ljson = create sailjson
ljson1 = create sailjson
ljson.setattribute( 'account','123456789')
ljson.setattribute( 'type', '1')
ljson.setattribute( 'pwd', '123456')
ls_json = ljson.getformatjson('')
//生成json格式结果{"account": "123456789","type": "1","pwd": "123456"}
三 解析json格式数据
json数据如{"code":1,"msg":"success","data":{"balance":10000,"status":1,"name":"hello","userId":10000659,"userType":1}}
string ls_json
sailjson ljson,ljson1,ljson_data
ljson = create sailjson
ljson1 = create sailjson
ljson1.parse(ls_json )
li_code = integer(ljson1.getattribute('code'))
ls_msg = string(ljson1.getattribute('msg'))
ljson_data = ljson1.getattribute("data")
ls_userid = string(ljson_data.getattribute('userId'))
ls_name = string(ljson_data.getattribute('name'))