| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 111 人关注过本帖
标题:发现json类的一个bug
只看楼主 加入收藏
sam_jiang
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:832
专家分:1275
注 册:2021-10-13
结帖率:97.06%
收藏
已结贴  问题点数:20 回复次数:1 
发现json类的一个bug
上次在《跟我一起学微信公众平台开发(二)》里提供了json类,今天发现有个bug,当属性值里有“:”“,”时,解析程序会出错,这两个符号是我们解析程序里字符串的起始判定符号,所以必须替换掉才可以进行解析。

用上次的类,运行下面的代码将会报错!
程序代码:
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编辑过]

搜索更多相关主题的帖子: IF 数组 this 替换 FOR 
2024-12-28 12:54
schtg
Rank: 12Rank: 12Rank: 12
来 自:Usa
等 级:贵宾
威 望:67
帖 子:1815
专家分:3509
注 册:2012-2-29
收藏
得分:20 
谢谢!
2024-12-28 20:29
快速回复:发现json类的一个bug
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026705 second(s), 10 queries.
Copyright©2004-2025, BCCN.NET, All Rights Reserved