![]() |
#2
schtg2024-12-28 20:29
|
用上次的类,运行下面的代码将会报错!

CLEAR
RELEASE ALL
PUBLIC ojson
*script=[{ "errcode": 0, "errmsg": "ok", "quota":{ "daily_limit": 0, "used": 0, "remain": 0}}]
script=[{"errcode":40164,"errmsg":"invalid ip 112.10.181.255 ipv6 ::ffff:112.10.181.255, not in whitelist rid: 676ee36c-33ea19f9-5885a393"}]
ojson=NEWOBJECT("json","myclass")
ojson.parse(script)
?ojson.getvalue("errmsg")
解决方案很简单,就是判断每对“”的里面文字是否有“:”“,”,如果有就用“& # 58”“& # 44”替换,最后再复原就可以了。
主要代码如下:
json.parse

LPARAMETERS jsonscript
*!* 12/28发现bug,当json属性的值里有“:”“,”符号时,解析程序出错
*!* 解决方案,解析前搜索每对引号对,把这两个字符替换掉,最后再复原。
LOCAL ckey,cstr,i,j,n,ccontent,ckey,cvalue,atemp,nleft,nright,jsarray,ncount,m
jsonscript=STRTRAN(jsonscript,CHR(9),"") &&清除tab键
jsonscript=STRTRAN(jsonscript,CHR(10),"") &&清除ctrl+enter
jsonscript=STRTRAN(jsonscript,CHR(13),"") &&清除换行符
jsonscript=allt(jsonscript) &&清除首尾空格
*!* ************最基本的json结构检查************
IF OCCURS("{",jsonscript)<>OCCURS("}",jsonscript) OR OCCURS("[",jsonscript)<>+OCCURS("]",jsonscript) OR MOD(OCCURS(["],jsonscript),2)<>0
MESSAGEBOX('{,[" 未成对!')
RETURN .f.
ENDIF
*!* 12/28修改,加入代码完成对“:”(:)“,”(,)字符的判断并替换
ncount=0
n=OCCURS(["],jsonscript)
FOR i=1 TO n/2
ccontent=STREXTRACT(jsonscript,["],["],2*i-1)
*!* 替换“:”
ncount=OCCURS([:],ccontent)
IF ncount<>0
ctemp=STRTRAN(ccontent,[:],"& # 58")
jsonscript=STRTRAN(jsonscript,ccontent,ctemp)
ENDIF
*!*
*!* 替换“,”
ccontent=STREXTRACT(jsonscript,["],["],2*i-1)
ncount=OCCURS([,],ccontent)
IF ncount<>0
ctemp=STRTRAN(ccontent,[,],"& # 44")
jsonscript=STRTRAN(jsonscript,ccontent,ctemp)
ENDIF
*!*
ENDFOR
*!*
this.jsscript=jsonscript
*****
*!* 先检查是不是包含json数组的复合结构
*!* 提取所有json数组,并以AJSON+编号予以替换,保存于jsonarraylist中
n=0
DO WHILE .t.
IF OCCURS("[",jsonscript)>0 &&说明json结构里有数组
DIMENSION jsonarraylist[n+1] &&用以保存json数组的内容
nleft =AT("[",jsonscript) &&确定第一个 "[" 的位置
i=0
*!* 下面这段代码确定与第一个 "[" 匹配的 "]" 的位置
DO WHILE .t.
i=i+1
nright=AT("]",jsonscript,i)
ccontent=SUBSTR(jsonscript,nleft,nright-nleft+1)
IF OCCURS("[",ccontent)<>OCCURS("]",ccontent)
LOOP
ELSE
EXIT
ENDIF
ENDDO
*!*
*!* ccontent=SUBSTR(jsonscript,nleft,nright-nleft+1) &&提取json数组的整体内容
n=n+1
jsarray="AJSON_"+TRANSFORM(n) &&准备替换掉数组的内容
jsonscript=STRTRAN(jsonscript,ccontent,jsarray)
jsonarraylist(n)=ccontent
LOOP
ELSE
*!* 2024/12.22 漏掉一种可能,没有数组,但是有json嵌套
IF OCCURS("{",jsonscript)>1
DIMENSION jsonarraylist[n+1]
nleft=AT("{",jsonscript,2)
nright=AT("}",jsonscript,1)
ccontent=SUBSTR(jsonscript,nleft,nright-nleft+1)
n=n+1
jsarray="OJSON_"+TRANSFORM(n)
jsonscript=STRTRAN(jsonscript,ccontent,jsarray)
jsonarraylist(n)=ccontent
loop
ELSE
EXIT
ENDIF
*!*
ENDIF
ENDDO
*!*
*!* 对替换所有数组后的json结构进行解析
DIMENSION atemp[1]
ncount=ALINES(atemp,jsonscript,9,",")
FOR i=1 TO ncount
ckey =ALLTRIM(STREXTRACT(STREXTRACT(atemp[i],"",":"),["],["]))
cvalue=STRtr(STREXTRACT(atemp[i],":",""),["],[])
cvalue=ALLTRIM(STRTRAN(cvalue,"}",""))
*!* 12/28加入,复原可能存在的“:”,“,”
cvalue=STRTRAN(cvalue,"& # 44",[,])
cvalue=STRTRAN(cvalue,"& # 58",[:])
*!*
this.Add(cvalue,ckey)
ENDFOR
*!*
*!* *!* 如果是复合结构,则复原json数组内容
*!* IF VARTYPE(jsonarraylist)!="U"
*!* FOR i=1 TO ALEN(jsonarraylist)
*!* cvalue="AJSON_"+TRANSFORM(i)
*!* FOR j=1 TO this.count
*!* IF TRANSFORM(this.Item(j))=cvalue
*!* ckey=this.GetKey(j)
*!* this.Remove(ckey)
*!* this.add(jsonarraylist[i],ckey)
*!* ENDIF
*!* ENDFOR
*!* ENDFOR
*!* ENDIF
*!* *!*
*!* 如果是复合结构,则复原json数组内容
IF VARTYPE(jsonarraylist)!="U"
FOR i=1 TO ALEN(jsonarraylist)
cvalue="AJSON_"+TRANSFORM(i)
m=this.count
FOR j=1 TO m
IF TRANSFORM(this.Item(j))=cvalue
ckey=this.GetKey(j)
this.Remove(ckey)
&ckey=NEWOBJECT([jsonarray],[myclass])
&ckey..name=ckey
&ckey..parse(jsonarraylist[i])
IF j=m
this.add(&ckey,ckey)
ELSE
this.Add(&ckey,ckey,j)
ENDIF
ENDIF
ENDFOR
ENDFOR
FOR i=1 TO ALEN(jsonarraylist)
cvalue="OJSON_"+TRANSFORM(i)
m=this.count
FOR j=1 TO m
IF TRANSFORM(this.Item(j))=cvalue
ckey=this.GetKey(j)
this.Remove(ckey)
&ckey=NEWOBJECT([json],[myclass])
&ckey..name=ckey
&ckey..parse(jsonarraylist[i])
IF j=m
this.add(&ckey,ckey)
ELSE
this.Add(&ckey,ckey,j)
ENDIF
ENDIF
ENDFOR
ENDFOR
ENDIF
*!*
json.getvalue代码也要稍作修改

PARAMETERS ckey,noccurrence
LOCAL i,j,nleft,nright,cchar,cvalue,n
cvalue=""
IF PARAMETERS()=1
noccurrence=1
ENDIF
n=AT(ckey,this.jsscript,noccurrence)
IF n>0
*!* 确定指定json属性的值的起始位置
nleft=n+LEN(ckey)
DO WHILE .t.
nleft=nleft+1
cchar=SUBSTR(this.jsscript,nleft,1)
IF cchar=":"
nleft=nleft+1 &&从":"后面一个字符开始
EXIT
ELSE
LOOP
ENDIF
ENDDO
*!*
DO WHILE .t.
cchar=ALLTRIM(SUBSTR(this.jsscript,nleft,1))
IF cchar=" " &&空格,冒号后面可能不小心输入了空格,剔除它
nleft=nleft+1
LOOP
ELSE
EXIT
ENDIF
ENDDO
IF cchar="[" &&说明是数组
*!*确定与"["匹配的"]"的位置
i=0
DO WHILE .t.
i=i+1
nright=AT("]",this.jsscript,i)
IF nright<nleft
LOOP
ELSE
cvalue=SUBSTR(this.jsscript,nleft,nright-nleft+1)
IF OCCURS("[",cvalue)=OCCURS("]",cvalue)
EXIT
ELSE
LOOP
ENDIF
ENDIF
ENDDO
ELSE &&否则就是普通数值
*!* 亦有可能是json嵌套,2024/12/22 加入json嵌套解读代码
IF cchar="{" &&说明值是一个json结构,然后找出“}”的位置
nright=nleft
DO WHILE .t.
nright=nright+1
cchar=SUBSTR(this.jsscript,nright,1)
IF cchar="}"
cvalue=SUBSTR(this.jsscript,nleft,nright-nleft+1)
EXIT
ELSE
LOOP
ENDIF
ENDDO
ELSE &&然后才是普通数值
cscript=this.jsscript+","
j=0
DO WHILE .t.
j=j+1
nright=AT(",",cscript,j)
IF nright<nleft
LOOP
ELSE
cvalue=SUBSTR(cscript,nleft,nright-nleft)
cvalue=STRTRAN(cvalue,["],"")
cvalue=STRTRAN(cvalue,[}],"")
cvalue=ALLTRIM(cvalue)
*!* 12/28加入,复原可能的“:”“,”
cvalue=STRTRAN(cvalue,"& # 44",",")
cvalue=STRTRAN(cvalue,"& # 58",":")
*!*
EXIT
ENDIF
ENDDO
ENDIF
*!*
ENDIF
ENDIF
RETURN cvalue
运行结果:
只有本站会员才能查看附件,请 登录
[此贴子已经被作者于2024-12-28 13:04编辑过]