文章目录
PB JSON 数据结构
JSON 语法
JSON语法规则
1.数据表示为 名称/值对
2.数据之间由逗号分隔
3.花括号 { } 保存JSON对象
4.方括号 [ ] 保存数组
{"code" : 1, "name" : "prime", "value" : [2,3,5,7,11,13]}
JSON 值
JSON数据的值可以是:
1.数值
{"item" : 3.14159265358979}
2.字符串
{"item" : "foobar"}
3.布尔值
{"item" : true}
4.null
{"item" : null}
5.数组
{"item" : [17,19,23,29,31,37]}
{"item" : ["foo","bar"]}
6.JSON对象
{"item" : {"subItem" : "foobar"}}
数组
数组的值可以是任何一种数据的值,包括数组本身
[2,3,5,7,11,13]
["foo","bar","baz"]
[true,false,true,false]
[null , {} , {"item" : [ "foo","bar"]} , [17,19,23,29,31,37] ]
PB JSON 数据结构使用
组装JSON
只需要一个方法 setItem
n_json ljson_main,ljson_value,ljson_list[]
any la_value[],la_empty[]
string ls_null
string ls_json
ljson_main = create n_json
ljson_value = create n_json
ljson_list[1] = create n_json
ljson_list[2] = create n_json
ljson_main.setItem("number_1",123) //设置数值
ljson_main.setItem("number_2",3.14) //设置数值
ljson_main.setItem("string_1","foo") //设置字符串
ljson_main.setItem("string_2","bar") //设置字符串
ljson_main.setItem("string_3",today()) //设置日期,自动转为字符串
ljson_main.setItem("boolean_1",false) //设置布尔值
setnull(ls_null)
ljson_main.setItem("null_1",ls_null) //设置null
ljson_value.setItem("value","value1")
ljson_main.setItem("json_1",ljson_value) //设置JSON对象
ljson_main.setItem("array_1",{2,3,5,7,11,13}) //设置数值列表
ljson_list[1].setItem("item","list1")
ljson_list[2].setItem("item","list2")
ljson_main.setItem("array_2",ljson_list) //设置JSON对象列表
la_value[1] = 100
la_value[2] = "200"
ljson_main.setItem("array_3",la_value) //设置混合类型列表
ljson_main.setItem("array_4",la_empty) //设置空列表
ljson_main.pretty_print = true //输出字符串自动换行美化格式
ls_json = ljson_main.getFormat()
destroy ljson_main
destroy ljson_value
destroy ljson_list[1]
destroy ljson_list[2]
return 0
以上代码执行完成后ls_json值为:
{
"number_1":123,
"number_2":3.14,
"string_1":"foo",
"string_2":"bar",
"string_3":"2019-03-30",
"boolean_1":false,
"null_1":null,
"json_1":{
"value":"value1"
},
"array_1":[2,3,5,7,11,13],
"array_2":[{
"item":"list1"
},{
"item":"list2"
}],
"array_3":[100,"200"],
"array_4":[]
}
解析JSON
string ls_json
n_json ljson_main
ls_json = '{' +&
'"corp":"MacroSoft",' +&
'"business":["software","computer science","energy"],' +&
'"employeeCount":3,' +&
'"employees": [' +&
'{ "firstName":"John" , "lastName":"Doe" },' +&
'{ "firstName":"Anna" , "lastName":"Smith" },' +&
'{ "firstName":"Peter" , "lastName":"Jones" }' +&
']' +&
'}'
ljson_main = create n_json
ljson_main.parse(ls_json) //解析JSON字符串
string ls_corp,ls_business[]
integer li_employee_count,i
n_json ljson_employee[]
string ls_firstname,ls_lastname
ls_corp = ljson_main.getItem("corp") //获取 corp 字符串
ls_business = ljson_main.getItem("business") //获取 business 字符串列表
li_employee_count = ljson_main.getItem("employeeCount") //获取 employeeCount 数值
ljson_main.getListJSON("employees",ljson_employee) //获取 employees JSON列表
for i= 1 to upperbound(ljson_employee) //循环遍历 employees 内部数据
ls_firstname = ljson_employee[i].getitem("firstName")
ls_lastname = ljson_employee[i].getitem("lastName")
next
destroy ljson_main
return 0
DataWindow与DataStore接口
数据窗内容输入JSON
dw_data.accepttext()
n_json ljson_data1,ljson_data2,ljson_data3,ljson_data4
string ls_data1,ls_data2,ls_data3,ls_data4
ljson_data1 = create n_json
ljson_data2 = create n_json
ljson_data3 = create n_json
ljson_data4 = create n_json
ljson_data1.setData("employees",dw_data) //数据窗全部内容作为列表设置到 employees 的值
ljson_data2.setDataRow("employees",dw_data,1,2) //数据窗第1到2行内容作为列表设置到 employees 的值
ljson_data3.setDataRow("employee",dw_data,3) //数据窗第3行内容作为JSON对象设置到 employee 的值
ljson_data4.setDataRow(dw_data,1) //数据窗第1行各字段数据设置到该JSON对象
ljson_data1.pretty_print = true
ljson_data2.pretty_print = true
ljson_data3.pretty_print = true
ljson_data4.pretty_print = true
ls_data1 = ljson_data1.getFormat()
ls_data2 = ljson_data2.getFormat()
ls_data3 = ljson_data3.getFormat()
ls_data4 = ljson_data4.getFormat()
destroy ljson_data1
destroy ljson_data2
destroy ljson_data3
destroy ljson_data4
return 0
代码执行后,字符串的值如下
// ls_data1的值
{
"employees":[{
"first_name":"Thomas",
"last_name":"Wade",
"age":45
},{
"first_name":"Beihai",
"last_name":"Zhang",
"age":36
},{
"first_name":"Jason",
"last_name":"Friday",
"age":33
}]
}
// ls_data2的值
{
"employees":[{
"first_name":"Thomas",
"last_name":"Wade",
"age":45
},{
"first_name":"Beihai",
"last_name":"Zhang",
"age":36
}]
}
// ls_data3的值
{
"employee":{
"first_name":"Jason",
"last_name":"Friday",
"age":33
}
}
// ls_data4的值
{
"first_name":"Thomas",
"last_name":"Wade",
"age":45
}
数据存储接口调用方式和数据窗完全相同
JSON内容输入数据窗
string ls_data
n_json ljson_data
ls_data = '{' +&
' "first_name":"Donald",' +&
' "last_name":"Trump",' +&
' "age":70' +&
'}'
ljson_data = create n_json
ljson_data.parse(ls_data)
ljson_data.exportDataRow(dw_data) //JSON内容输出到数据窗最后一行
destroy ljson_data
return 0
执行后结果如下
string ls_data
n_json ljson_data
ls_data = '{' +&
' "presidents":[{' +&
' "first_name":"Donald",' +&
' "last_name":"Trump",' +&
' "age":70' +&
' },{' +&
' "first_name":"Vladimir",' +&
' "last_name":"Putin",' +&
' "age":66' +&
' }]' +&
'}'
ljson_data = create n_json
ljson_data.parse(ls_data)
ljson_data.exportData("presidents",dw_data) //JSON 的 presidents 值输出到数据窗
destroy ljson_data
return 0
执行后结果如下
数据存储接口调用方式和数据窗完全相同
表达式搜索与路径搜索
表达式支持这些格式:
item[x] //item值列表的第x项
item[x:y] //item值列表的第x至第y项
item[x:] //item值列表第x项开始之后所有值
item[:y] //item值列表自第1项至第y项所有值
item[:] //item值列表
item //item值(可以是列表或非列表)
路径就是斜线 / 后面跟上表达式连接而成
表达式搜索或路径搜索返回的结果必须赋值给对应类型的数据结构,没有该类型数据结构的情况只能先赋值给any类型
string ls_data
n_json ljson_data
dec{8} ldc_pi,ldc_e
long ll_primes[],ll_prime
string ls_name[]
ls_data = '{ "primes" : [2,3,5,7,11,13,17,19,23,29,31,37] ,' +&
' "transcendentalNumbers" : [ {"name":"pi" , "value":3.14159265} , {"name":"e" , "value":2.71828183} ] '+&
'} '
ljson_data = create n_json
ljson_data.parse(ls_data)
// 表达式搜索
ll_primes = ljson_data.getItemExp("primes[:]") // => [2,3,5,7,11,13,17,19,23,29,31,37]
ll_primes = ljson_data.getItemExp("primes[2:4]") // => [3,5,7]
ll_primes = ljson_data.getItemExp("primes[:6]") // => [2,3,5,7,11,13]
ll_primes = ljson_data.getItemExp("primes[7:]") // => [17,19,23,29,31,37]
ll_prime = ljson_data.getItemExp("primes[7]") // => 17
// 路径搜索
ldc_pi = ljson_data.getItemPath("/transcendentalNumbers[1]/value") // => 3.14159265
ls_name= ljson_data.getItemPath("/transcendentalNumbers/name") // => ["pi","e"]
destroy ljson_data
return 0
其他方法与属性
1.重置数据结构
ljson_data.reset()
2.删除键值对
ljson_data.delItem("foo")
3.键重命名
ljson_data.rename("foo","bar")
4.判断是否包含键
string ls_foo
if ljson_data.contains("foo") then
ls_foo = ljson_data.getitem("foo")
end if
5.输出字符串键的命名风格
实例变量 public string item_name_style
支持类型:
STYLE_LOWER //小写命名 e.g. user_name
STYLE_UPPER //大写命名 e.g. USER_NAME
STYLE_CAMEL //骆驼命名 e.g. userName
STYLE_PASCAL //帕斯卡命名 e.g. UserName
PB JSON 数据结构源代码
解析字符方法要点
私有方法:
_parse_json
_parse_list
_parse_value
逐字符读取JSON字符串,读取到花括号 { 时调用 _parse_json 解析JSON对象,读取到方括号 [ 时调用 _parse_list 解析列表,读取到冒号 : 时调用 _parse_value 解析值,三个方法内部互相递归,完全解析任意格式JSON字符串。
输出字符方法要点
私有方法:
_get_format_json
_get_format_list
_get_format_value
遍历数据结构每个键值对,需要输出JSON字符串时调用 _get_format_json ,需要输出列表字符串时调用 _get_format_list ,需要输出值字符串时调用 _get_format_value ,三个方法内部互相递归,将任意的JSON实例输出到字符串。
源代码
代码拷贝到文本编辑器,另存为 n_json.sru,导入pbl
新版本:PB JSON工具n_json新版本
发现BUG请留言或私信,以便修正(QQ:768310524 TEL:18649713925)
$PBExportHeader$n_json.sru
forward
global type n_json from nonvisualobject
end type
type st_item from structure within n_json
end type
type st_name_exp from structure within n_json
end type
end forward
type st_item from structure
string name
any value
end type
type st_name_exp from structure
string name
boolean islist
long idx_begin
long idx_end
end type
global type n_json from nonvisualobject
event readme ( )
end type
global n_json n_json
type variables
private:
string items_idx='|' // |item1:1|item2:2|
st_item item_list[]
string jsonstr
char jsonc[]
long idx,jsonlen
public:
string date_format = 'yyyy-mm-dd'
string time_format = 'hh:mm:ss'
string datetime_format = 'yyyy-mm-dd hh:mm:ss'
string item_name_style = '' // STYLE_LOWER STYLE_UPPER STYLE_CAMEL STYLE_PASCAL
boolean pretty_print
constant string STYLE_LOWER = 'STYLE_LOWER'
constant string STYLE_UPPER = 'STYLE_UPPER'
constant string STYLE_CAMEL = 'STYLE_CAMEL'
constant string STYLE_PASCAL = 'STYLE_PASCAL'
end variables
forward prototypes
public subroutine reset ()
public function any getitem (string item_name)
public function integer delitem (string item_name)
public function string getformat ()
public function integer setdata (string item_name, any data)
public function integer setdatarow (any data, long row)
public function integer setdatarow (string item_name, any data, long row)
private function integer _get_idx (string item_name)
private function string _trans_name (string item_name)
public function integer setdatarow (string item_name, any data, long begin_row, long end_row)
private function string _get_format_json (integer level)
private subroutine _skip ()
private function integer _parse_list (ref any value[])
private function integer _parse_value (ref any value)
private subroutine _regenerate_items_idx ()
private function string _get_format_list (any value[], integer level)
private function string _get_format_value (any value, integer level)
public function integer setitem (string item_name, any item_value)
public function long exportdatarow (any data)
public function long exportdata (string item_name, any data)
private function integer _parse_json (n_json ajson)
private function date _to_date (string s)
private function time _to_time (string s)
private function datetime _to_datetime (string s)
public function long getlistjson (string item_name, ref n_json rjson[])
public function any getitempath (string item_path)
private function integer _parse_expression (string expression, ref st_name_exp rst_name_exp)
private function integer _trans_data_row (any data, long row, ref st_item rst_item[])
public function any getitemexp (string item_expression)
public function integer rename (string item_name, string new_name)
private function integer _trans_list (ref any value[])
private function integer _trans_value (ref any value)
public function integer parse (string s)
public function boolean contains (string item_name)
end prototypes
public subroutine reset ();st_item lst_items[]
char lc[]
item_list = lst_items
items_idx = '|'
jsonstr = ''
jsonc = lc
idx = 0
jsonlen = 0
end subroutine
public function any getitem (string item_name);any la_item_value
int i
setnull(la_item_value)
i = _get_idx(item_name)
if i > 0 then la_item_value = item_list[i].value
return la_item_value
end function
public function integer delitem (string item_name);int li_idx,i
st_item lst_items[]
li_idx = _get_idx(item_name)
if li_idx < 1 then return -1
for i = 1 to li_idx - 1
lst_items[i] = item_list[i]
next
for i = li_idx + 1 to upperbound(item_list)
lst_items[i - 1] = item_list[i]
next
item_list = lst_items
_regenerate_items_idx()
return 0
end function
public function string getformat ();return _get_format_json(1)
end function
public function integer setdata (string item_name, any data);return setdatarow(item_name,data,1,data.dynamic rowcount())
end function
public function integer setdatarow (any data, long row);long i
st_item lst_item[]
if _trans_data_row(data,row,lst_item) < 0 then return -1
for i = 1 to upperbound(lst_item)
item_list[upperbound(item_list) + 1] = lst_item[i]
next
_regenerate_items_idx()
return 0
end function
public function integer setdatarow (string item_name, any data, long row);n_json ljson
ljson = create n_json
ljson.date_format = date_format
ljson.time_format = time_format
ljson.datetime_format = datetime_format
ljson.item_name_style = item_name_style
ljson.pretty_print = pretty_print
ljson.setdatarow(data,row)
return setitem(item_name,ljson)
end function
private function integer _get_idx (string item_name);long ll_pos1,ll_pos2
ll_pos1 = pos(items_idx,'|'+item_name+':')
if ll_pos1 < 1 then return -1
ll_pos1 += len(item_name) + 2
ll_pos2 = pos(items_idx,'|',ll_pos1+1)
return integer(mid(items_idx, ll_pos1, ll_pos2 - ll_pos1))
end function
private function string _trans_name (string item_name);string ls_name
char lc[]
long i
boolean lb_trans_flag
//命名规则转换
choose case item_name_style //user_name
case STYLE_UPPER //USER_NAME
ls_name = upper(item_name)
case STYLE_LOWER //user_name
ls_name = lower(item_name)
case STYLE_CAMEL //userName
lc = item_name
do while i < len(lc)
i += 1
if lc[i] = '_' then
lb_trans_flag = true
continue
end if
if lb_trans_flag then
ls_name += upper(string(lc[i]))
lb_trans_flag = false
else
ls_name += lower(string(lc[i]))
end if
loop
case STYLE_PASCAL //UserName
lc = item_name
lb_trans_flag = true
do while i < len(lc)
i += 1
if lc[i] = '_' then
lb_trans_flag = true
continue
end if
if lb_trans_flag then
ls_name += upper(string(lc[i]))
lb_trans_flag = false
else
ls_name += lower(string(lc[i]))
end if
loop
case else
return item_name
end choose
return ls_name
end function
public function integer setdatarow (string item_name, any data, long begin_row, long end_row);long i,j
n_json ljson_list[]
st_item lst_item[],lst_null[]
for i = begin_row to end_row
lst_item = lst_null
if _trans_data_row(data,i,lst_item) < 0 then return -1
j += 1
ljson_list[j] = create n_json
ljson_list[j].date_format = date_format
ljson_list[j].time_format = time_format
ljson_list[j].datetime_format = datetime_format
ljson_list[j].item_name_style = item_name_style
ljson_list[j].pretty_print = pretty_print
ljson_list[j].item_list = lst_item
ljson_list[j]._regenerate_items_idx()
next
return setitem(item_name,ljson_list)
end function
private function string _get_format_json (integer level);int i
string ls_tab
string ls_json,ls_name_value
if pretty_print then ls_tab = fill('~t',level - 1)
for i = 1 to upperbound(item_list)
ls_name_value = ''
if pretty_print then ls_name_value += '~r~n~t' + ls_tab
ls_name_value += '"'+_trans_name(item_list[i].name)+'"'+':'
ls_name_value += _get_format_value(item_list[i].value,level)
if i < upperbound(item_list) then ls_name_value += ','
ls_json += ls_name_value
next
if pretty_print then ls_json += '~r~n'+ls_tab
return '{'+ls_json+'}'
end function
private subroutine _skip ();char c
do
idx += 1
c = jsonc[idx]
loop while c=' ' or c='~r' or c='~n' or c='~t' or c='~b' or c='~f'
end subroutine
private function integer _parse_list (ref any value[]);long i
any la_list[],la_value_list[]
_skip()
do until jsonc[idx] = ']'
i += 1
if _parse_value(la_list[i]) < 0 then return -1
_skip()
if jsonc[idx] = ',' then _skip()
loop
value = la_list
return 0
end function
private function integer _parse_value (ref any value);string ls_value
n_json ljson
any la_value,la_list[]
long ll_pos
choose case jsonc[idx]
case '{'
ljson = create n_json
if _parse_json(ljson) < 0 then return -1
la_value = ljson
case '['
if _parse_list(la_list) < 0 then return -1
la_value = la_list
case '"'
idx += 1
do until jsonc[idx] = '"' or idx > jsonlen
if jsonc[idx] = '\' then
idx += 1
if not (jsonc[idx] = '"' or jsonc[idx] = '\') then
choose case jsonc[idx]
case 't'
ls_value += '~t'
case 'r'
ls_value += '~r'
case 'n'
ls_value += '~n'
case 'f'
ls_value += '~f'
case 'b'
ls_value += '~b'
case else
return -1
end choose
idx += 1
continue
end if
end if
ls_value = ls_value + jsonc[idx]
idx += 1
loop
// do
// ll_pos = pos(jsonstr,'"',idx)
// if ll_pos <= 0 then return -1
// if jsonc[ll_pos - 1] = '\' then
// ls_value += mid(jsonstr,idx,ll_pos - idx - 1)
// idx = ll_pos + 1
// else
// ls_value += mid(jsonstr,idx,ll_pos - idx)
// idx = ll_pos
// exit
// end if
// loop until idx >= jsonlen
la_value = ls_value
case '0' to '9','+','-',&
't','f',&
'n'
do until jsonc[idx] = ',' or jsonc[idx] = ']' or jsonc[idx] = '}' or idx > jsonlen
ls_value = ls_value + jsonc[idx]
idx += 1
loop
idx -= 1
if isnumber(ls_value) then
if pos(ls_value,'E') > 0 or pos(ls_value,'e') > 0 then
la_value = double(ls_value)
elseif pos(ls_value,'.') > 0 then
la_value = dec(ls_value)
else
la_value = long(ls_value)
end if
else
choose case ls_value
case 'true'
la_value = true
case 'false'
la_value = false
case 'null'
setnull(la_value)
case else
return -1
end choose
end if
case else
return -1
end choose
value = la_value
return 0
end function
private subroutine _regenerate_items_idx ();int i
items_idx = '|'
for i = 1 to upperbound(item_list)
items_idx += item_list[i].name + ':' + string(i) + '|'
next
end subroutine
private function string _get_format_list (any value[], integer level);long i
string ls_item_list
for i = 1 to upperbound(value)
ls_item_list += _get_format_value(value[i],level)
if i < upperbound(value) then ls_item_list += ','
next
return '['+ls_item_list+']'
end function
private function string _get_format_value (any value, integer level);string ls_value
n_json ljson
char lc[]
long i
if upperbound(value) >= 0 then
ls_value = _get_format_list(value,level)
elseif classname(value) = classname(this) then
ljson = value
ljson.item_name_style = item_name_style
ljson.pretty_print = pretty_print
ls_value = ljson._get_format_json(level + 1)
else
if isnull(classname(value)) then
ls_value = 'null'
else
choose case classname(value)
case 'string'
lc = string(value)
for i = 1 to upperbound(lc)
// if lc[i] = '"' or lc[i] = '\' then ls_value += '\'
// ls_value = ls_value + lc[i]
choose case lc[i]
case '"','\'
ls_value += '\' + lc[i]
case '~r'
ls_value += '\r'
case '~n'
ls_value += '\n'
case '~t'
ls_value += '\t'
case '~f'
ls_value += '\f'
case '~b'
ls_value += '\b'
case else
ls_value = ls_value + lc[i]
end choose
next
ls_value = '"'+ls_value+'"'
case else
ls_value = string(value)
end choose
end if
end if
return ls_value
end function
public function integer setitem (string item_name, any item_value);st_item lst_item
int li_idx
any la_item_value
_trans_value(item_value)
li_idx = _get_idx(item_name)
if li_idx < 0 then
lst_item.name = item_name
lst_item.value = item_value
li_idx = upperbound(item_list)+1
item_list[li_idx] = lst_item
items_idx += item_name+':'+string(li_idx)+'|'
else
item_list[li_idx].value = item_value
end if
return li_idx
end function
public function long exportdatarow (any data);long ll_row
int i
string ls_colname,ls_coltype
string ls_item_name
any la_item_value
string ls_cls
string ls_value,ls_date,ls_time,ls_datetime
if upperbound(data) >= 0 then return -1
choose case data.dynamic typeof()
case DataWindow!,DataStore!
case else
return -1
end choose
ll_row = data.dynamic insertrow(0)
for i = 1 to upperbound(item_list)
ls_item_name = item_list[i].name
la_item_value = item_list[i].value
if upperbound(la_item_value) >= 0 then continue
ls_colname = data.dynamic describe(ls_item_name+".name")
if ls_colname = '!' or ls_colname = '?' or ls_colname = '' or isnull(ls_colname) then continue
ls_coltype = data.dynamic describe(ls_item_name+".coltype")
ls_cls = classname(la_item_value)
choose case lower(mid(ls_coltype,1,4))
case 'char' //-->string
if not (ls_cls = 'string') then continue
case 'deci'/*decimal*/,'numb'/*number*/,'long','ulon'/*ulong*/,'real'
if not (ls_cls = 'decimal' or &
ls_cls = 'double' or &
ls_cls = 'integer' or &
ls_cls = 'long' or &
ls_cls = 'unsignedinteger' or &
ls_cls = 'unsignedlong' or &
ls_cls = 'real') then continue
case 'date','time' // date datetime time
if not (ls_cls = 'string') then continue
ls_value = la_item_value
if ls_coltype = 'date' then
la_item_value = _to_date(ls_value)
elseif ls_coltype = 'datetime' then
la_item_value = _to_datetime(ls_value)
elseif ls_coltype = 'time' then
la_item_value = _to_time(ls_value)
end if
case else
continue
end choose
data.dynamic setitem(ll_row,ls_item_name,la_item_value)
next
return ll_row
end function
public function long exportdata (string item_name, any data);any la_list[]
any la_value
long ll_count,i
n_json ljson
long ll_export
la_value = getitem(item_name)
ll_count = upperbound(la_value)
if ll_count < 0 then
la_list[1] = la_value
else
la_list = la_value
end if
for i = 1 to ll_count
if not classname(la_list[i]) = classname(this) then continue
ljson = la_list[i]
ljson.exportdatarow(data)
ll_export += 1
next
return ll_export
end function
private function integer _parse_json (n_json ajson);string ls_item_name
any la_value,la_list[]
_skip()
do while idx < jsonlen
if jsonc[idx] = '}' then return 0
if jsonc[idx] <> '"' then return -1
ls_item_name = ''
idx += 1
do until jsonc[idx] = '"'
ls_item_name = ls_item_name + jsonc[idx]
idx += 1
loop
_skip()
if jsonc[idx] <> ':' then return -1
_skip()
if _parse_value(la_value) < 0 then return -1
ajson.setitem(ls_item_name,la_value)
_skip()
if jsonc[idx] = ',' then
_skip()
elseif jsonc[idx] = '}' then
return 0
end if
loop
return 0
end function
private function date _to_date (string s);date ld
string ls_year,ls_month,ls_day
setnull(ld)
if len(s) <> len(date_format) then return ld
ls_year = mid(s,pos(date_format,'yyyy'),4)
ls_month = mid(s,pos(date_format,'mm'),2)
ls_day = mid(s,pos(date_format,'dd'),2)
if not (isnumber(ls_year) and isnumber(ls_month) and isnumber(ls_day)) then return ld
ld = date(integer(ls_year),integer(ls_month),integer(ls_day))
if string(ld,date_format) <> s then setnull(ld)
return ld
end function
private function time _to_time (string s);time lt
string ls_hour,ls_minute,ls_second
setnull(lt)
if len(s) <> len(time_format) then return lt
ls_hour = mid(s,pos(time_format,'hh'),2)
ls_minute = mid(s,pos(time_format,'mm'),2)
ls_second = mid(s,pos(time_format,'ss'),2)
if not (isnumber(ls_hour) and isnumber(ls_minute) and isnumber(ls_second)) then return lt
lt = time(integer(ls_hour),integer(ls_minute),integer(ls_second))
if string(lt,time_format) <> s then setnull(lt)
return lt
end function
private function datetime _to_datetime (string s);datetime ldt
date ld
time lt
string ls_year,ls_month,ls_day
string ls_hour,ls_minute,ls_second
setnull(ldt)
if len(s) <> len(datetime_format) then return ldt
ls_year = mid(s,pos(date_format,'yyyy'),4)
ls_month = mid(s,pos(date_format,'mm'),2)
ls_day = mid(s,pos(date_format,'dd'),2)
ls_hour = mid(s,pos(time_format,'hh'),2)
ls_minute = mid(s,lastpos(time_format,'mm'),2)
ls_second = mid(s,pos(time_format,'ss'),2)
if not (isnumber(ls_year) and isnumber(ls_month) and isnumber(ls_day) and isnumber(ls_hour) and isnumber(ls_minute) and isnumber(ls_second)) then return ldt
ld = date(integer(ls_year),integer(ls_month),integer(ls_day))
lt = time(integer(ls_hour),integer(ls_minute),integer(ls_second))
ldt = datetime(ld,lt)
if string(ldt,datetime_format) <> s then setnull(ldt)
return ldt
end function
public function long getlistjson (string item_name, ref n_json rjson[]);any la_value,la_list[]
n_json ljson[]
long i
la_value = getitem(item_name)
if upperbound(la_value) < 0 then return -1
la_list = la_value
for i = 1 to upperbound(la_list)
if upperbound(la_list[i]) >= 0 then return -1
if isnull(la_list[i]) then return -1
if classname(la_list[i]) <> classname(this) then return -1
next
rjson = la_list
return upperbound(rjson)
end function
public function any getitempath (string item_path);any la,la_value,la_list_get[],la_list_set[]
n_json ljson_value
long i,ll_len
char lc[]
string ls_item_expression,ls_next_path
lc =item_path
ll_len = upperbound(lc)
if ll_len <= 0 then return la
i = 1
if lc[i] <> '/' then return la
i += 1
do until lc[i] = '/'
ls_item_expression = ls_item_expression + lc[i]
i += 1
if i > ll_len then exit
loop
la_value = getitemexp(ls_item_expression)
if i > ll_len then return la_value
ls_next_path = mid(item_path,i)
if upperbound(la_value) >= 0 then
la_list_get = la_value
for i = 1 to upperbound(la_list_get)
if classname(la_list_get[i]) = classname(this) then
ljson_value = la_list_get[i]
la_list_set[i] = ljson_value.getitempath(ls_next_path)
else
la_list_set[i] = la
end if
next
return la_list_set
else
if classname(la_value) = classname(this) then
ljson_value = la_value
return ljson_value.getitempath(ls_next_path)
else
return la
end if
end if
return la
end function
private function integer _parse_expression (string expression, ref st_name_exp rst_name_exp);char lc[]
string ls_item_name,ls_idx_begin,ls_idx_end
long ll_idx_begin,ll_idx_end
long i = 1
if not match(expression,'.+\[.+\]$') then return -1
lc = expression
do until lc[i] = '['
ls_item_name = ls_item_name + lc[i]
i += 1
loop
i += 1
do until lc[i] = ':' or lc[i] = ']'
ls_idx_begin = ls_idx_begin + lc[i]
i += 1
loop
if ls_idx_begin = '' then ls_idx_begin = '1'
if not isnumber(ls_idx_begin) then return -1
ll_idx_begin = long(ls_idx_begin)
if lc[i] = ':' then
i += 1
do until lc[i] = ']'
ls_idx_end = ls_idx_end + lc[i]
i += 1
loop
if ls_idx_end = '' then ls_idx_end = '0'
if not isnumber(ls_idx_end) then return -1
ll_idx_end = long(ls_idx_end)
if ll_idx_end > 0 and ll_idx_end < ll_idx_begin then return -1
rst_name_exp.islist = true
else
ll_idx_end = ll_idx_begin
rst_name_exp.islist = false
end if
rst_name_exp.name = ls_item_name
rst_name_exp.idx_begin = ll_idx_begin
rst_name_exp.idx_end = ll_idx_end
return 0
end function
private function integer _trans_data_row (any data, long row, ref st_item rst_item[]);int li_colcount
string ls_colname[],ls_coltype[]
long i,j,ll_rowcount
any la_value
if upperbound(data) >= 0 then return -1
choose case data.dynamic typeof()
case DataWindow!,DataStore!
case else
return -1
end choose
ll_rowcount = data.dynamic rowcount()
if row > ll_rowcount then return -1
li_colcount = integer(data.dynamic describe("datawindow.column.count"))
for i = 1 to li_colcount
if data.dynamic describe("#"+string(i)+".tag") = 'ETH' then continue
j += 1
ls_colname[j] = data.dynamic describe("#"+string(i)+".name")
ls_coltype[j] = data.dynamic describe(ls_colname[j]+'.coltype')
next
for i = 1 to upperbound(ls_colname)
choose case lower(left(ls_coltype[i],4))
case 'char' //string
la_value = data.dynamic getitemstring(row,ls_colname[i])
if isnull(la_value) then la_value = ''
case 'deci'/*decimal*/
la_value = data.dynamic getitemdecimal(row,ls_colname[i])
case 'numb'/*number*/,'long','ulon'/*ulong*/,'real'
la_value = data.dynamic getitemnumber(row,ls_colname[i])
case 'date'
if ls_coltype[i] = 'date' then
la_value = string(data.dynamic getitemdate(row,ls_colname[i]),date_format)
else //datetime
la_value = string(data.dynamic getitemdatetime(row,ls_colname[i]),datetime_format)
end if
if isnull(la_value) then la_value = ''
case 'time'
la_value = string(data.dynamic getitemtime(row,ls_colname[i]),time_format)
if isnull(la_value) then la_value = ''
case else
setnull(la_value)
end choose
rst_item[i].name = ls_colname[i]
rst_item[i].value = la_value
next
return upperbound(rst_item)
end function
public function any getitemexp (string item_expression);any la_value,la_item_value
any la_list_get[],la_list_set[]
long i
st_name_exp lst_name_exp
setnull(la_item_value)
if _parse_expression(item_expression,lst_name_exp) < 0 then return getitem(item_expression)
la_value = getitem(lst_name_exp.name)
if isnull(la_value) then return la_item_value
if upperbound(la_value) < max(lst_name_exp.idx_begin,lst_name_exp.idx_end) then return la_item_value
la_list_get = la_value
if lst_name_exp.isList then
if lst_name_exp.idx_end = 0 then lst_name_exp.idx_end = upperbound(la_list_get)
for i = 1 to lst_name_exp.idx_end - lst_name_exp.idx_begin + 1
la_list_set[i] = la_list_get[lst_name_exp.idx_begin + i - 1]
next
la_item_value = la_list_set
else
la_item_value = la_list_get[lst_name_exp.idx_begin]
end if
return la_item_value
end function
public function integer rename (string item_name, string new_name);int li_idx
li_idx = _get_idx(item_name)
if li_idx < 0 then return -1
item_list[li_idx].name = new_name
_regenerate_items_idx()
return li_idx
end function
private function integer _trans_list (ref any value[]);long i
for i = 1 to upperbound(value)
_trans_value(value[i])
next
return 0
end function
private function integer _trans_value (ref any value);any la_value
if upperbound(value) >= 0 then
_trans_list(value)
return 0
end if
if isnull(value) then return 0
choose case classname(value)
case classname(this)
la_value = value
case 'string'
la_value = value
case 'integer','unsignedinteger','long','unsignedlong','decimal','double','real'
la_value = value
case 'boolean'
la_value = value
case 'date'
la_value = string(value,date_format)
case 'time'
la_value = string(value,time_format)
case 'datetime'
la_value = string(value,datetime_format)
case else
setnull(la_value)
end choose
value = la_value
return 0
end function
public function integer parse (string s);reset()
jsonstr = s
jsonc = s
jsonlen = upperbound(jsonc)
_skip()
if jsonc[idx] <> '{' then return -1
if _parse_json(this) < 0 then return -1
return 0
end function
public function boolean contains (string item_name);if _get_idx(item_name) < 0 then
return false
else
return true
end if
end function
on n_json.create
call super::create
TriggerEvent( this, "constructor" )
end on
on n_json.destroy
TriggerEvent( this, "destructor" )
call super::destroy
end on
备注
某些PB版本调用getlistjson方法报错 error:type mismatch in array to object conversion,需要修改getlistjson方法:
public function long getlistjson (string item_name, ref n_json rjson[]);any la_value,la_list[]
long i
la_value = getitem(item_name)
if upperbound(la_value) < 0 then return -1
la_list = la_value
for i = 1 to upperbound(la_list)
if upperbound(la_list[i]) >= 0 then return -1
if isnull(la_list[i]) then return -1
if classname(la_list[i]) <> classname(this) then return -1
rjson[i] = la_list[i]
next
//rjson = la_list
return upperbound(rjson[])
在PB WebService服务端运行时,私有方法_trans_list可能会报错,解决方式代码修改如下:
private function integer _trans_list (ref any value[]);long i
any la_value
for i = 1 to upperbound(value)
la_value = value[i]
_trans_value(la_value)
value[i] = la_value
next
return 0