PLJSON开源库介绍(三)

本文详细介绍PLJSON库的使用方法,包括字符串转换、处理大文本、使用JSONPATH导航、NULL值处理等内容,并通过示例代码展示如何操作JSON数据。

本文来自李明子csdn博客(http://blog.csdn.net/free1985),商业转载请联系博主获得授权,非商业转载请注明出处!
5.8 转换字符串
对于JSON、JSON_LIST和JSON_VALUE都可以通过to_char函数转换为字符串。to_char函数有两个参数,其中“spaces”表示是否填充空格,默认为“true”;“chars_per_line”表示每行的字符数,默认值为“0”,表示不限制。
to_char函数在以上几节(如对象构造)的示例中已多次出现,此处不再单独给出示例。

5.9 处理大文本
很多时候,json对象中会包含大文本,此时已超过varchar2的限制,只能使用clob类型。JSON、JSON_LIST和JSON_VALUE均包含方法to_clob。下面是该方法的使用示例:

--JSON大文本示例
  procedure EG_CLOB is
    --json对象
    aJsonObj json;
    --源文本
    srcClob clob;
    --目标文本
    desClob clob;
  begin
    --对于实际应用,目标文本的指针应从已建立的记录中获取,
    --这里简化为新建clob对象
    desClob := empty_clob();
    dbms_lob.createtemporary(desClob, true);
    --假设json对象key1的值是个大文本
    aJsonObj := json('{"key1":"a long long text..."}');

    --直接用pljson存入会在clob值的两侧有双引号
    srcClob := empty_clob();
    dbms_lob.createtemporary(srcClob, true);
    aJsonObj.get('key1').to_clob(srcClob, true);
    dbms_lob.copy(desClob, srcClob, dbms_lob.getlength(srcClob) - 2, 1, 2);
    dbms_lob.freetemporary(srcClob);

    dbms_output.put_line(desClob);
    dbms_lob.freetemporary(desClob);
  end;

5.10 使用JSON PATH导航
JSON和JSON_LIST对象都包含一组导航方法用于直接操作JSON或JSON数组中指定位置的值。其中,path方法用于获取指定位置的值;path_put方法用于添加或修改指定位置的值;path_remove方法用于删除指定位置的值。
以上方法的核心参数是用于导航的path字符串。这个path字符串是按层次组成的一组“[]”序列。其中,每个“[]”中放置该层次中的序号(名值对序号或数组中的元素序号)或key值。
比如图5-2所示的JSON字符串,[1][2]代表的导航过程如图5-3所示,[1][2][1]代表的导航过程如图5-4所示,[“L1K1”][1][“L2K1”]代表的导航过程如图5-5所示。

JSON PATH导航示例
图5-2 JSON PATH导航示例

[1][2]代表的导航过程
图5-3 [1][2]代表的导航过程

[1][2][1]代表的导航过程
图5-4 [1][2][1]代表的导航过程

["L1K1"][1]["L2K1"]代表的导航过程
图5-5 [“L1K1”][1][“L2K1”]代表的导航过程

JSON PATH的示例代码如下:

--JSON PATH示例
  procedure EG_PATH is
    --json对象
    aJsonObj json;
    --另一个json对象
    anotherJsonObj json;
  begin
    aJsonObj := json('{"Level1Key1":[{"Level2Key1":"a"},{"Level2Key1":"b"}]
    ,"Level1Key2":123}');
    --输出为{"Level2Key1":"b"}
    aJsonObj.path('[1][2]').print;
    --输出为b
    aJsonObj.path('[1][2][1]').print;
    --输出为a
    aJsonObj.path('["Level1Key1"][1]["Level2Key1"]').print;

    anotherJsonObj := json(aJsonObj.path('[1][1]'));
    anotherJsonObj.put('Level2Key2', true);
    aJsonObj.path_put('[1][1]', anotherJsonObj);
    --输出为{"Level1Key1":[{"Level2Key1":"a","Level2Key2":true},
    --{"Level2Key1":"b"}],"Level1Key2":123}
    aJsonObj.print;

    aJsonObj.path_put('[1][2]["Level2Key2"]', false);
    --输出为{"Level1Key1":[{"Level2Key1":"a","Level2Key2":true},
    --{"Level2Key1":"b","Level2Key2":false}],"Level1Key2":123}
    aJsonObj.print;

    aJsonObj.path_remove('["Level1Key1"][2]');
    --输出为{"Level1Key1":[{"Level2Key1":"a","Level2Key2":true}],"Level1Key2":123}
    aJsonObj.print;

  end;

5.11 关于NULL
PLJSON支持JSON名值对的值为null。对于字符串类型(VARCHAR2),与PL/SQL类似,null与空字符串(“”)等价。对于其它值类型,用null表示空值。示例代码如下:

--JSON null值示例
  procedure EG_NULL is
    --json对象
    aJsonObj json;
    --一个verchar2
    aVerchar2 varchar2(200);
    --一个number
    aNumber number;
  begin
    aJsonObj := json('{"key1":null,"key2":""}');
    aJsonObj.put('key3', '');
    aVerchar2 := null;
    aJsonObj.put('key4', aVerchar2);
    aNumber := null;
    aJsonObj.put('key5', aNumber);
    --输出为{"key1":null,"key2":"","key3":"",
    --"key4":"","key5":null}
    aJsonObj.print;
  end;

5.12 值引用 or 对象引用?
将JSON对象加入其它JSON对象或者JSON数组时涉及到值引用和对象引用的问题。即A对象被加入B对象,之后A对象被修改,B对象里包含的A对象会跟着修改吗?答案是否定的。即在JSON对象和JSON数组中引入其它JSON对象或JSON数组时是值引用的。下面是一个测试示例:

--JSON引用示例
  procedure EG_Refrence is
    --json对象
    aJsonObj json;
    --json数组
    aJsonArray json_list;
  begin
    aJsonObj   := json('{"key1":"1","key2":"2"}');
    aJsonArray := json_list();
    aJsonArray.append(aJsonObj.to_json_value, 1);
    --输出为[{"key1":"1","key2":"2"}]
    aJsonArray.print;
    aJsonObj.put('key1', 'a');
    --输出为[{"key1":"1","key2":"2"}]
    aJsonArray.print;
  end;

6 对源码的改造

PLJSON对字符进行了一些处理,有时我们可能需要通过修改源码改变默认行为。这些修改主要集中在JSON_PRINTER.escapeString中。修改内容涉及到对特殊符号的转义及对Unicode字符的处理。下面是修改示例:

     --20150512屏蔽,避免对双引号添加转义字符
      --when chr(34) then buf := '\"';
        when chr(47) then
          if (escape_solidus) then
            buf := '\/';
          end if;
        when chr(92) then
          --20150820修改,避免clob对“\”字符的添加转义字符
          --buf := '\\';
          null;
        else
          null;
          /*20150314屏蔽,避免将汉字转换为utf8码值
          if(ascii(buf) < 32) then
            buf := '\u'||replace(substr(to_char(ascii(buf), 'XXXX'),2,4), ' ', '0');
          elsif (ascii_output) then
            buf := replace(asciistr(buf), '\', '\u');
          end if;
          */

(完)

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值