pbai 发表于 5 天前

PBIDEA:用 uo_json 的 set/get 与路径语法操作 JSON

本帖最后由 pbai 于 2026-8-14 09:22 编辑

PBIDEA:用 uo_json 的 set/get 与路径语法操作 JSON

做接口对接、配置文件、前端数据交换时,绕不开 JSON。PBIDEA 的 uo_json 把「建树、取值、改值」压成两个动作:set 和 get,再用一套 /items/0/text 的路径语法直接定位到数组里的任意一层。本文只讲清楚一件事:怎么用 set/get 配合路径语法,读写一棵带数组的 JSON,且中途自动建树、不会踩空。

一、核心结论先放这儿


[*]set(key, value):键不存在就自动创建,支持嵌套路径,先 set 父再 set 子也行,顺序随意。
[*]get(key, ref value):返回 boolean 表示是否取到,第二参是输出。取不到不会报错崩溃。
[*]路径语法:"a/b/c" 走对象,"a/0/b" 走数组第 0 个元素(0 基)。数组下标用数字即可。
[*]数字默认当 double 存,get 到 long/int 会自动转;要当字符串保留位数用 GetString。


二、最小可运行示例

下面这段代码不依赖任何业务,粘进按钮的 clicked 事件就能跑。它构造了一个带 items 数组的对象,再原样读回来:


uo_json js
js = create uo_json

// 1) 顶层字段:set 自动建树,先写谁都行
js.set("name", "小明")
js.set("age", 32)             // 数字按 double 存
js.set("vip", true)         // 布尔

// 2) 数组 + 路径语法:/items/0/text 表示 items 数组第 0 项的 text 字段
js.set("/items/0/text", "搜索")
js.set("/items/0/icon", "search.svg")
js.set("/items/1/text", "设置")
js.set("/items/1/icon", "gear.svg")

// 3) 取回——get 返回 boolean,取不到时变量保持原值,可给默认值
string ls_name, ls_first, ls_icon
if js.get("name", ls_name) then
    // 成功
end if
js.get("/items/0/text", ls_first)   // -> "搜索"
js.get("/items/1/icon", ls_icon)    // -> "gear.svg"

// 4) 数字:get 到 long 自动转;想拿字符串用 GetString
long ll_age
js.get("age", ll_age)               // -> 32
string ls_age
ls_age = js.GetString("age")      // -> "32"

// 5) 数组长度 & 遍历
long ll_cnt, i
ll_cnt = js.ArrCount("items")       // -> 2
string ls_t
for i = 0 to ll_cnt - 1
    js.get("/items/" + string(i) + "/text", ls_t)
    // 依次得到 "搜索"、"设置"
next

// 6) 导出
string ls_out
ls_out = js.ToString(true, false, false)// 美化输出,不转 unicode
destroy js


三、set 的几个易混点

set 的第二个参数类型

set 是重载的,第二参可以是 string / number(int,long,double,decimal...) / boolean / blob / uo_json / 数组。传 blob 时默认走 BASE64 编码(常量 SetBlob=1);想存原始字节序用 SetBytes=2 形式(带第三个参数 SetType)。日常配置基本只用 string/number/boolean。

路径里数组下标从 0 开始

这是最容易写错的地方。/items/1/text 是第 2 个元素。下标写错不会报错,只是 get 返回 false、取不到值——所以取数组前先用 ArrCount 确认长度,别硬取。

想直接塞一整个数组

可以用数组形式一次 set:


string ls_tags[] = {"pb", "ide", "json"}
js.set("tags", ls_tags)          // tags 变成 ["pb","ide","json"]
long n
n = js.ArrCount("tags")          // -> 3


四、从字符串 / 文件反向解析

接口返回的报文、本地配置文件,都是「先有字符串,再解析成对象」:


uo_json j2
j2 = create uo_json

// 解析内存字符串
if j2.Parse('{"code":0,"msg":"ok","data":["a","b"]}') then
    long ll_code
    j2.get("code", ll_code)      // -> 0
end if

// 解析文件(中文路径注意编码)
if j2.ParseFile("menu_cn.json") then
    // 后续同样用 get / 路径语法
end if

// 转成 UTF-8 BLOB,直接交给 uo_httpclient 发出去
blob b_body = j2.ToUTF8()

destroy j2


Parse 还有 Parse(str, removeEscape)、Parse(str, removeEscape, NumAsString) 等重载:网络报文常带转义,removeEscape=true 可顺手清掉;NumAsString=true 让所有数字以字符串形式保留(避免 1.0 变 1、丢精度)。

五、改值、删值、清空


js.Replace("name", "小红")       // 替换已存在的节点
js.Remove("/items/0")            // 删除数组第 0 项(后面的下标会自动前移)
js.Remove("vip")               // 删除顶层字段
js.Clear()                     // 清空整棵对象


注意 Remove("/items/0") 删的是数组项,删掉后原第 1 项变成新的第 0 项——遍历时别用「先算长度再固定下标」的写法去删,会越界或漏删。

六、什么时候用便利方法

字段多、类型杂时,用 GetString / GetLong / GetDouble / GetLongLong 比 get(..., ref) 少写一行类型声明:


strings
long    l
doubled
s = js.GetString("name", "")   // 带默认值,取不到返回 ""
l = js.GetLong("age")
d = js.GetDouble("score")


GetKeys(ref keys[]) 能拿出全部顶层 key(含类型),做「通用遍历 / 不确定结构」时很实用。

七、小结

记住一条主线就够用:create uo_json → set(路径, 值) 建树 → get(路径, ref 变量) 取值(先判返回值)→ ToString/ToUTF8 导出。路径语法 /a/0/b 让「数组里套对象、对象里再套数组」的深层结构,也能一行定位。下一篇我们接着看怎么用它组装 HTTP 请求体发出去。
页: [1]
查看完整版本: PBIDEA:用 uo_json 的 set/get 与路径语法操作 JSON

免责声明:
本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:Admin@SybaseBbs.com