檢視原始碼 json (stdlib v6.2)
用於編碼和解碼 JSON 的函式庫。
此模組實作 EEP68。
編碼器和解碼器都完全符合 RFC 8259 和 ECMA 404 標準。解碼器使用 JSONTestSuite 進行測試。
摘要
型別
可使用 json:encode/1
編碼的簡單 JSON 值。
函式
從 Binary
解析 JSON 值。
從 Binary
解析 JSON 值。
繼續解析 JSON 值的位元組串流。
開始解析 JSON 值的位元組串流。
產生對應於 Term
的 JSON。
產生對應於 Term
的 JSON。
json:encode/1
使用的原子預設編碼器。
json:encode/1
使用的二進位資料作為 JSON 字串的預設編碼器。
將二進位資料作為產生純 ASCII JSON 的 JSON 字串的編碼器。
json:encode/1
使用的浮點數作為 JSON 數字的預設編碼器。
json:encode/1
使用的整數作為 JSON 數字的預設編碼器。
將鍵值對列表編碼為 JSON 物件的編碼器。
將鍵值對列表編碼為 JSON 物件的編碼器。
json:encode/1
使用的列表作為 JSON 陣列的預設編碼器。
json:encode/1
使用的映射作為 JSON 物件的預設編碼器。
將映射編碼為 JSON 物件的編碼器。
json:encode/1
使用的預設編碼器。
產生對應於 Term
的格式化 JSON。
產生對應於 Term
的格式化 JSON。
產生對應於 Term
的格式化 JSON。
將鍵值對列表格式化為 JSON 物件的函式。
將鍵值對列表格式化為 JSON 物件的函式。
json:format/1
使用的預設格式化函式。
型別
-opaque continuation_state()
-type decode_value() :: integer() | float() | boolean() | null | binary() | [decode_value()] | #{binary() => decode_value()}.
-type decoders() :: #{array_start => array_start_fun(), array_push => array_push_fun(), array_finish => array_finish_fun(), object_start => object_start_fun(), object_push => object_push_fun(), object_finish => object_finish_fun(), float => from_binary_fun(), integer => from_binary_fun(), string => from_binary_fun(), null => term()}.
-type encode_value() :: integer() | float() | boolean() | null | binary() | atom() | [encode_value()] | encode_map(encode_value()).
可使用 json:encode/1
編碼的簡單 JSON 值。
函式
-spec decode(binary()) -> decode_value().
從 Binary
解析 JSON 值。
支援基本資料映射
JSON | Erlang |
---|---|
數字 | integer() | float() |
布林值 | true | false |
空值 | null |
字串 | binary() |
物件 | #{binary() => _} |
錯誤
- 如果
Binary
包含不完整的 JSON 值,則error(unexpected_end)
- 如果
Binary
包含未預期的位元組或無效的 UTF-8 位元組,則error({invalid_byte, Byte})
- 如果
Binary
包含無效的 UTF-8 跳脫字元,則error({unexpected_sequence, Bytes})
範例
> json:decode(<<"{\"foo\": 1}">>).
#{<<"foo">> => 1}
從 Binary
解析 JSON 值。
類似於 decode/1
,不同之處在於解碼過程可以使用 Decoders
中指定的回呼函式進行自訂。回呼函式會使用 Acc
值作為初始累加器。
Binary
中任何剩餘、未解析的資料都會被傳回。
預設回呼函式
所有回呼函式都是選擇性的。如果未提供,它們將會回退到 decode/1
函式使用的實作。
- 對於
array_start
:fun(_) -> [] end
對於
array_push
:fun(Elem, Acc) -> [Elem | Acc] end
- 對於
array_finish
:fun(Acc, OldAcc) -> {lists:reverse(Acc), OldAcc} end
- 對於
object_start
:fun(_) -> [] end
對於
object_push
:fun(Key, Value, Acc) -> [{Key, Value} | Acc] end
- 對於
object_finish
:fun(Acc, OldAcc) -> {maps:from_list(Acc), OldAcc} end
- 對於
float
:fun erlang:binary_to_float/1
- 對於
integer
:fun erlang:binary_to_integer/1
- 對於
string
:fun (Value) -> Value end
- 對於
null
: 原子null
錯誤
- 如果
Binary
包含未預期的位元組或無效的 UTF-8 位元組,則error({invalid_byte, Byte})
- 如果
Binary
包含無效的 UTF-8 跳脫字元,則error({unexpected_sequence, Bytes})
- 如果
Binary
包含不完整的 JSON 值,則error(unexpected_end)
範例
將物件鍵解碼為原子
> Push = fun(Key, Value, Acc) -> [{binary_to_existing_atom(Key), Value} | Acc] end.
> json:decode(<<"{\"foo\": 1}">>, ok, #{object_push => Push}).
{#{foo => 1},ok,<<>>}
-spec decode_continue(binary() | end_of_input, Opaque :: term()) -> {Result :: dynamic(), Acc :: dynamic(), binary()} | {continue, continuation_state()}.
繼續解析 JSON 值的位元組串流。
類似於 decode_start/3
,如果函式返回 {continue, State}
並且沒有更多資料,則使用 end_of_input
而不是二進位資料。
> {continue, State} = json:decode_start(<<"{\"foo\":">>, ok, #{}).
> json:decode_continue(<<"1}">>, State).
{#{foo => 1},ok,<<>>}
> {continue, State} = json:decode_start(<<"123">>, ok, #{}).
> json:decode_continue(end_of_input, State).
{123,ok,<<>>}
-spec decode_start(binary(), dynamic(), decoders()) -> {Result :: dynamic(), Acc :: dynamic(), binary()} | {continue, continuation_state()}.
開始解析 JSON 值的位元組串流。
類似於 decode/3
,但當可以解析完整的 JSON 值時返回,或者針對不完整資料返回 {continue, State}
,當有更多資料可用時,可以將 State
提供給 decode_continue/2
函式。
-spec encode(encode_value()) -> iodata().
產生對應於 Term
的 JSON。
支援基本資料映射
Erlang | JSON |
---|---|
integer() | float() | 數字 |
true | false | 布林值 |
null | 空值 |
binary() | 字串 |
atom() | 字串 |
list() | 陣列 |
#{binary() => _} | 物件 |
#{atom() => _} | 物件 |
#{integer() => _} | 物件 |
這等效於 encode(Term, fun json:encode_value/2)
。
範例
> iolist_to_binary(json:encode(#{foo => <<"bar">>})).
<<"{\"foo\":\"bar\"}">>
產生對應於 Term
的 JSON。
可以使用 Encoder
回呼函式進行客製化。此回呼函式會針對所有要編碼的資料遞迴呼叫,並預期返回對應的 JSON 編碼,格式為 iodata。
此模組中的各種 encode_*
函式可用於協助建構此類回呼函式。
範例
一個使用啟發式方法來區分鍵值對的類物件列表與普通列表的編碼器
> encoder([{_, _} | _] = Value, Encode) -> json:encode_key_value_list(Value, Encode);
> encoder(Other, Encode) -> json:encode_value(Other, Encode).
> custom_encode(Value) -> json:encode(Value, fun(Value, Encode) -> encoder(Value, Encode) end).
> iolist_to_binary(custom_encode([{a, []}, {b, 1}])).
<<"{\"a\":[],\"b\":1}">>
json:encode/1
使用的原子預設編碼器。
將原子 null
編碼為 JSON null
,原子 true
和 false
編碼為 JSON 布林值,並將其他所有內容編碼為 JSON 字串,並使用對應的二進位資料呼叫 Encode
回呼函式。
json:encode/1
使用的二進位資料作為 JSON 字串的預設編碼器。
錯誤
- 如果二進位資料包含不完整的 UTF-8 序列,則會返回
error(unexpected_end)
。 - 如果二進位資料包含無效的 UTF-8 序列,則會返回
error({invalid_byte, Byte})
。
將二進位資料作為產生純 ASCII JSON 的 JSON 字串的編碼器。
對於任何非 ASCII 的 Unicode 字元,都會使用對應的 \\uXXXX
序列。
錯誤
- 如果二進位資料包含不完整的 UTF-8 序列,則會返回
error(unexpected_end)
。 - 如果二進位資料包含無效的 UTF-8 序列,則會返回
error({invalid_byte, Byte})
。
json:encode/1
使用的浮點數作為 JSON 數字的預設編碼器。
json:encode/1
使用的整數作為 JSON 數字的預設編碼器。
將鍵值對列表編碼為 JSON 物件的編碼器。
接受具有原子、二進位資料、整數或浮點數鍵的列表。
將鍵值對列表編碼為 JSON 物件的編碼器。
接受具有原子、二進位資料、整數或浮點數鍵的列表。驗證產生的 JSON 物件中不會產生重複的鍵。
錯誤
如果存在重複項,則會引發 error({duplicate_key, Key})
。
json:encode/1
使用的列表作為 JSON 陣列的預設編碼器。
-spec encode_map(encode_map(dynamic()), encoder()) -> iodata().
json:encode/1
使用的映射作為 JSON 物件的預設編碼器。
接受具有原子、二進位資料、整數或浮點數鍵的映射。
將映射編碼為 JSON 物件的編碼器。
接受具有原子、二進位資料、整數或浮點數鍵的映射。驗證產生的 JSON 物件中不會產生重複的鍵。
錯誤
如果存在重複項,則會引發 error({duplicate_key, Key})
。
json:encode/1
使用的預設編碼器。
對 Value
中的所有值遞迴呼叫 Encode
。
-spec format(Term :: encode_value()) -> iodata().
產生對應於 Term
的格式化 JSON。
與 encode/1
類似,但增加了用於格式化的空格。
> io:put_chars(json:format(#{foo => <<"bar">>, baz => 52})).
{
"baz": 52,
"foo": "bar"
}
ok
-spec format(Term :: encode_value(), Opts :: map()) -> iodata(); (Term :: dynamic(), Encoder :: formatter()) -> iodata().
產生對應於 Term
的格式化 JSON。
等效於 format(Term, fun json:format_value/3, Options)
或 format(Term, Encoder, #{})
產生對應於 Term
的格式化 JSON。
與 encode/2
類似,可以使用 Encoder
回呼函式和 Options
進行客製化。
Options
可以包含 'indent' 以指定每層的空格數,以及 'max' 以粗略限制列表的寬度。
當遞迴遍歷 'Term' 時,Encoder
將會收到一個 'State' 引數,其中包含與其他資料合併的 'Options' 映射。
此模組中的 format_value/3
或各種 encode_*
函式可用於協助建構此類回呼函式。
> formatter({posix_time, SysTimeSecs}, Encode, State) ->
TimeStr = calendar:system_time_to_rfc3339(SysTimeSecs, [{offset, "Z"}]),
json:format_value(unicode:characters_to_binary(TimeStr), Encode, State);
> formatter(Other, Encode, State) -> json:format_value(Other, Encode, State).
>
> Fun = fun(Value, Encode, State) -> formatter(Value, Encode, State) end.
> Options = #{indent => 4}.
> Term = #{id => 1, time => {posix_time, erlang:system_time(seconds)}}.
>
> io:put_chars(json:format(Term, Fun, Options)).
{
"id": 1,
"time": "2024-05-23T16:07:48Z"
}
ok
將鍵值對列表格式化為 JSON 物件的函式。
接受具有原子、二進位資料、整數或浮點數鍵的列表。
-spec format_key_value_list_checked([{term(), term()}], Encoder :: formatter(), State :: map()) -> iodata().
將鍵值對列表格式化為 JSON 物件的函式。
接受具有原子、二進位資料、整數或浮點數鍵的列表。驗證產生的 JSON 物件中不會產生重複的鍵。
錯誤
如果存在重複項,則會引發 error({duplicate_key, Key})
。
json:format/1
使用的預設格式化函式。
對 Value
中的所有值遞迴呼叫 Encode
,並縮排物件和列表。