一些JSON相关的函数

JSON作为一种轻量的数据传输格式,越来越受到人们的青睐。下面是我仿照Prototype的一些实现。

JSONFilter:/^///*-secure-([/s/S]*)/*///s*$/,
unfilterJSON:function(json,filter) {
    return json.replace((filter || dom.JSONFilter), function(a,b){
        return b || ""
    });
},

JSONFilter完全抄自Prototype,因为后台基本上只会传输两种格式的东西给我们——文本(xmlhttp.responseText)与XML(xmlhttp.responseXML)。如果要json,我们可以eval一下,或者使用现代浏览器提供的JSON.parse方法。但问题就出在eval中,很容易出现XSS攻击。如果文本是注释就可以避免这问题,在Prototype中还检察一下请求的来源。对于自家的网站的请求,我们完全可以在请求前处理一下,让它变成如下格式:

var text = '/*-secure-/n{"name": "Violet", "occupation": "character", "age": 25}/n*/'
 dom.unfilterJSON(text)
// -> '{"name": "Violet", "occupation": "character", "age": 25}'

到时我们用unfilterJSON函数提取合法的字段来eval就没问题了。

第二个函数,判断字符串是否符合JSON的格式。JSON是有固定的格式,要求键必须被双引号括起来。下面的函数提取自json2

isJSONText:function(json){//
    return /^[/],:{}/s]*$/.test(json.replace(///(?:["////bfnrt]|u[0-9a-fA-F]{4})/g, "@")
        .replace(/"[^"///n/r]*"|true|false|null|-?/d+(?:/./d*)?(?:[eE][+/-]?/d+)?/g, "]")
        .replace(/(?:^|:|,)(?:/s*/[)+/g, ""));
},

第三个函数,将符合JSON的格式的文本变成JSON对象。第二参数用于指明此文本是否安全(如,是否同源请求)。如果能用原生对象的parse方法就用原生的,否则动态解析它。之所以不用eval,是因为ecma那帮人头脑发热,想禁掉它。

        evalJSON: function( json ,sanitize) {  
            if ( !is(json,"String") || !json )
                return null;
            json = dom.unfilterJSON(json);
            //判定是否符合JSON的格式 from http://json.org/json2.js
            if ( !sanitize || dom.isJSONText(json) ) {
                return window.JSON && window.JSON.parse ?
                window.JSON.parse( json ) : (new Function("return " + json))();
            } else {
                throw  "Invalid JSON: " + json;
            }
        }
//http://www.21kaiyun.com
var data =dom.evalJSON( '{ "name": "Violet", "occupation": "character" }');
data.name;
//-> "Violet"

第四函数,将JSON对象变成文本。

// http://www.21kaiyun.com

//21世纪开运网 

//   var a = [1,2,3,4,{aa:8}]; puts(dom.toJSON(a))
toJSON:function(obj){
    if (window.JSON && window.JSON.stringify) {
        return JSON.stringify(obj)
    }
    if (typeof window.uneval == 'function') {
        return uneval(obj);
    }
    if (typeof obj == 'object') {
        if (!obj) {
            return 'null';
        }
        var list = [];
        if (dom.is(obj,"Array")) {
            for (var i=0,n=obj.length;i <n;i++) {
                list.push(dom.toJSON(obj[i]));
            }
            return '[' + list.join(',') + ']';
        } else {
            for (var prop in obj) {
                if(obj[has](prop))
                    list.push('"' + prop + '":' + dom.toJSON(obj[prop]));
            }
            return '{' + list.join(',') + '}';
        }
    } else if (typeof obj == 'string') {
        return '"' + obj.replace(/(["'])/g, '//$1') + '"';
    } else {
        return new String(obj);
    }
},
toJSON : function(obj) {
    if(is(window.JSON,"JSON")){
        return JSON.stringify(obj)
    }
    function f(n) {
        return n < 10 ? '0' + n : n;
    }
    var escapable = /[///"/x00-/x1f/x7f-/x9f/u00ad/u0600-/u0604/u070f/u17b4/u17b5/u200c-/u200f/u2028-/u202f/u2060-/u206f/ufeff/ufff0-/uffff]/g;
    var meta = {
        '/b': '//b',
        '/t': '//t',
        '/n': '//n',
        '/f': '//f',
        '/r': '//r',
        '"' : '//"',
        '//': '////'
    };
    function _char(c) {
        return meta[c] ? meta[c] :'//u'+('0000'+(+(c.charCodeAt(0))).toString(16)).slice(-4);
    }
    function _string(s) {
        return '"' + s.replace(escapable, _char) + '"';
    }
    if(is(obj,"Date")){
        return  '"' + obj.getUTCFullYear() + '-' +
        f(obj.getUTCMonth() + 1) + '-' +
        f(obj.getUTCDate())      + 'T' +
        f(obj.getUTCHours())     + ':' +
        f(obj.getUTCMinutes())   + ':' +
        f(obj.getUTCSeconds())   + 'Z"' ;
    }else if(is(obj,"Number")){
        return isFinite(obj) ? obj+'' : 'null';
    }else if(is(obj,"Boolean")){
        return  obj+''
    }else if(is(obj,"String")){
        return _string(obj)
    }else if(obj === null){
        return "null"
    }else if(is(obj,"Array")){
        return '[' + (dom.filter(obj,function(value){
            return dom.toJSON(value) !== undefined;
        })).join(', ') + ']';
    }else if(is(obj,"Object")){
        var results = [];
        dom.each(obj,function(value,key){
            value = dom.toJSON(value)
            if (!value)
                results.push(dom.toJSON(key) + ': ' + value);
        });
        return '{' + results.join(', ') + '}';
    }else {
        return undefined;
    }
},

 

Is函数

 

目前最精确的判定方法(不包括自定义类型)

//2010.6.1更新
        var is = function (obj,type) {
        return (type === "Null" && obj === null) ||
        (type === "Undefined" && obj === void 0 ) ||
        (type === "Number" && isFinite(obj)) ||
         Object.prototype.toString.call(obj).slice(8,-1) === type;
    },

用法如下:

//***************示例一,判定数组与函数
        var forEach = function(array,fn,bind){
          if(is(array,"Array") && is(Array.forEach,"Function")){
            array.forEach(fn,bind);
          }else{
            for(var i=0,n=array.length;i<n;i++){
              i in array && fn.call(bind,array[i],i,array)
            }
          }
        }
//***************示例二,判定null
var a = null
alert(is(a,"Null"))
//***************示例二,判定undefined
var b
alert(is(b,"Undefined"))

另一个变种,直接返回表示类型的字符串

var getType = function (obj) {
  var _toString = Object.prototype.toString,undefined;
  return obj === null? "Null":
    obj === undefined ? "Undefined":
    _toString.call(obj).slice(8,-1);
};

用法:

var arr = [1,2,3,4]
      alert(getType(arr));//Array
      var nil = null
      alert(getType(nil))//Null
      var und ;
      alert(getType(und))//Undefined
      var spans = document.getElementsByTagName("span");
      alert(getType(spans)) //HTMLCollection
      alert(getType(spans[0].childNodes))//NodeList
//2010.7.20
function isA (thing, canon) {
  // special case for null and undefined
  if (thing == null || canon == null) {
    return thing === canon;
  }
  return Object.getPrototypeOf(Object(thing)) == Object.getPrototypeOf(Object(canon));
}
function isBool (thing) {
  return isA(thing, true);
}
function isNumber (thing) {
  return isA(thing, 0) && isFinite(thing);
}
function isString (thing) {
  return isA(thing, "");
}
<think>我们被要求使用中文回答问题,并在回答结束时提出3-5个相关问题,且第一行必须为“§§相关问题§§”,禁止换行分散。 问题:postgresql json解析函数 回答:PostgreSQL提供了丰富的JSON解析函数,用于处理JSON数据类型。以下是一些常用的函数: 1. `->` 操作符:用于通过键获取JSON对象字段的值(返回JSON类型)。 示例:`SELECT '{"name": "John", "age": 30}'::json -> 'name'` 返回 `"John"`(JSON字符串)。 2. `->>` 操作符:用于通过键获取JSON对象字段的值,但返回为文本类型(text)。 示例:`SELECT '{"name": "John", "age": 30}'::json ->> 'name'` 返回 `John`(文本)。 3. `#>` 操作符:通过路径(路径元素数组)获取JSON对象中的嵌套值(返回JSON类型)。 示例:`SELECT '{"a": {"b": {"c": 1}}}'::json #> '{a,b,c}'` 返回 `1`(JSON数字)。 4. `#>>` 操作符:通过路径获取JSON对象中的嵌套值,返回文本类型。 示例:`SELECT '{"a": {"b": {"c": 1}}}'::json #>> '{a,b,c}'` 返回 `1`(文本)。 5. `json_extract_path` 函数:与 `#>` 类似,但使用可变参数指定路径(返回JSON)。 示例:`SELECT json_extract_path('{"a": {"b": {"c": 1}}}', 'a', 'b', 'c')` 返回 `1`(JSON数字)。 6. `json_extract_path_text` 函数:与 `#>>` 类似,返回文本。 示例:`SELECT json_extract_path_text('{"a": {"b": {"c": 1}}}', 'a', 'b', 'c')` 返回 `1`(文本)。 7. `json_array_elements` 函数:将JSON数组展开为一组JSON元素。 示例:`SELECT json_array_elements('[1, "a", true]'::json)` 返回三行:`1`, `"a"`, `true`(每行一个JSON值)。 8. `jsonb_path_query` 函数(仅适用于JSONB):使用JSON路径查询提取元素。 示例:`SELECT jsonb_path_query('{"a": [1,2,3]}', '$.a[*] ? (@ > 1)')` 返回大于1的数组元素(JSONB数组)。 另外,PostgreSQL还提供了许多其他函数,如 `json_object_keys`(获取对象的所有键)、`json_typeof`(获取JSON值的类型)等。 注意:PostgreSQL中有两种JSON类型:`json`(存储的是文本的精确副本)和 `jsonb`(二进制格式,支持索引,效率更高)。上述函数大多同时支持两种类型,但有些函数可能只支持其中一种。 §§相关问题§§ 1. PostgreSQL中JSONJSONB类型有什么区别? 2. 如何在PostgreSQL中创建JSON类型的索引以提高查询性能? 3. 如何将PostgreSQL中的JSON数组转换为行? 4. 如何使用PostgreSQL的JSON函数更新JSON数据? 5. 在PostgreSQL中,如何将查询结果转换为JSON格式? </think>### PostgreSQL JSON解析函数详解 PostgreSQL 提供了强大的 JSON 解析函数集,支持在 SQL 中直接处理 JSON 数据。以下是核心函数及用法: #### 1. **字段提取** - `->` 获取 JSON 对象字段(返回 JSON 类型) ```sql SELECT '{"name":"Alice","age":30}'::json -> 'name'; -- 结果: "Alice" ``` - `->>` 获取 JSON 对象字段(返回 text 类型) ```sql SELECT '{"name":"Alice","age":30}'::json ->> 'age'; -- 结果: 30 (text) ``` #### 2. **路径解析** - `#>` 按路径提取(返回 JSON 类型) ```sql SELECT '{"user":{"profile":{"email":"a@example.com"}}}'::json #> '{user,profile,email}'; -- 结果: "a@example.com" ``` - `#>>` 按路径提取(返回 text 类型) ```sql SELECT '{"user": {"id": 100}}'::json #>> '{user,id}'; -- 结果: 100 (text) ``` #### 3. **数组展开** - `json_array_elements()` 展开 JSON 数组为多行 ```sql SELECT json_array_elements('[1, "a", true]'::json); -- 返回三行: 1, "a", true ``` #### 4. **键值处理** - `json_object_keys()` 获取 JSON 对象的所有键 ```sql SELECT json_object_keys('{"x":1, "y":2}'); -- 结果: x, y (两行) ``` #### 5. **类型转换** - `jsonb_pretty()` 格式化 JSONB 输出(仅 JSONB 类型) ```sql SELECT jsonb_pretty('{"info": {"address": "Paris"}}'::jsonb); ``` #### 6. **条件查询** - `@?` / `@@` 运算符(JSONB 专用) ```sql SELECT '{"tags":["postgres","db"]}'::jsonb @? '$.tags[*] ? (@ == "postgres")'; -- 检查是否存在匹配: true ``` > **注意**: > - 优先使用 `jsonb` 类型(二进制存储,支持索引)而非 `json`(文本存储) > - 完整函数列表见 [PostgreSQL JSON 文档](https://www.postgresql.org/docs/current/functions-json.html)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值