/
984.txt
1616 lines (1254 loc) · 86.8 KB
/
984.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
[31] [DFN[[RUBY[[[JSON]]][ジェイソン]]]] ([DFN[JavaScript Object Notation]] / [DFN[JavaScript オブジェクト記法]])
は、 [[JavaScript]] における[[オブジェクト・リテラル]]の[[部分集合]]によって[[オブジェクト]]や[[配列]]を表記するデータ交換書式です。
[[JavaScript]] を始め数多くの[[言語]]で[[ライブラリー]]が整備されており、
汎用的な[[データ構造]]の交換形式として広く用いられています。
[FIG(quote)[
[FIGCAPTION[
[30] [CITE@en[JSON]] ([TIME[2011-07-09 12:55:13 +09:00]] 版) <http://www.json.org/>
]FIGCAPTION]
>JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.
]FIG]
* 仕様書
[REFS[
- [132] '''[CITE[Standard ECMA-404]] ([TIME[2013-10-09 12:19:30 +09:00]] 版) <http://www.ecma-international.org/publications/standards/Ecma-404.htm>'''
- [314] [CITE@en[RFC 7159 - The JavaScript Object Notation (JSON) Data Interchange Format]] ([TIME[2015-07-12 00:13:37 +09:00]] 版) <http://tools.ietf.org/html/rfc7159#section-11>
- [331] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-09-30 22:54:01 +09:00]] 版) <https://html.spec.whatwg.org/#json-mime-type>
]REFS]
[219] 現在 [[JSON]] は [DFN[[[ECMA-404]]]] によって定義されています。
[HISTORY[
[315] 以前は [[ES5]] に定義が含まれていましたが、
[[ES6]] は [[ECMA-404]] を参照する形になっています。
]HISTORY]
[220] それとは別に [[RFC 7159]] にもやや異なる定義があります。
[[ECMA-404]] を参照しつつも、独自の異なる内容も含んでいます。
混乱を招きかねないので、あまり参照するべきではないでしょう。
ただし [[MIME型]] [CODE(MIME)@en[[[application/json]]]] は [[RFC 7159]]
で定義されています ([[ECMA-404]] では定義されていません)。
[HISTORY[
[316] [[RFC 7159]] は [[RFC 7158]]
を再出版したもので、 [[RFC 4627]] の改訂版でもあります。
[[RFC 4627]] はながらく [[JSON]] の定義として参照されていましたが、
現行仕様とは異なるため、歴史的文脈以外で参照するべきではありません。
]HISTORY]
[HISTORY[
[221] [[json.org]] にも定義が掲載されていますが、現在ではこれは仕様ではなく、半公式の解説と理解するべきでしょう。
]HISTORY]
[222] 以降の各項目では [[ECMA-404]] での定義に加えて、各仕様での歴史的な定義についても触れます。
全体としての経緯は歴史の項を参照してください。
* JSON 値
[37] [DFN[[[JSON]] [RUBYB[値]@en[value]]]] には次の種類があります [SRC[>>132, >>3 1.]]。
[FIG(list)[
- [38] [RUBYB[[[プリミティブ型]]]@en[primitive types]]
-- [39] [RUBYB[[[文字列]]]@en[string]]
-- [40] [RUBYB[[[数値]]]@en[number]]
-- [41] [[boolean]] - [[true]], [[false]]
-- [42] [[null]]
- [43] [RUBYB[[[構造化型]]]@en[structured types]]
-- [44] [RUBYB[[[オブジェクト]]]@en[object]]
-- [45] [RUBYB[[[配列]]]@en[array]]
]FIG]
[FIG(railroad)[
= *
== 空白
= |
== [[文字列]]
== [[数値]]
== [CODE[[[true]]]]
== [CODE[[[false]]]]
== [CODE[[[null]]]]
== [[オブジェクト]]
== [[配列]]
= *
== 空白
]FIG]
** オブジェクト
[48] [[オブジェクト]]は、 [CODE(char)[[['''{''']]]] の後に0個[[以上]]の[RUBYB[[[メンバー]]]@en[member]]を
[CODE(char)[[[,]]]] で区切って並べ、最後に [CODE(char)[[['''}''']]]] が来る文字列として表されます。
[SRC[>>132, >>3 2.2.]]
[FIG(railroad)[
= [CODE[[[{]]]]
= ?
== メンバー
== *
=== [CODE[[[,]]]]
=== メンバー
= [CODE[[[}]]]]
]FIG]
[52] 最後の[[メンバー]]の後に [CODE(char)[[[,]]]] を入れることは認められていません。
;; [244] [[JSON]] の派生元である [[ES3]] がこれを認めておらず、当時の [[IE]] も対応していなかったためです。
[273] メンバーは、名前と値の組であり、[[文字列]]の後に [CODE(char)[[[:]]]] が来て、
その後に値が来ます。 [SRC[>>132, >>3 2.2.]]
[FIG(railroad)[
= *
== 空白
= [[文字列]]
= *
== 空白
= [CODE[[[:]]]]
= *
== 空白
= [[JSON値]]
]FIG]
[226] [[メンバー]]の個数に制約はありません。
[227] [[メンバー]]の順序に意味はあるかどうかは仕様上言及されていません。
[225] [[オブジェクト]]とその[[名前]]や値の解釈は仕様上定義されていません。 [[JavaScript]]
では[[オブジェクト]]に、 [[Perl]] では[[ハッシュ参照]]に対応付けられるなど、[[言語]]と環境により異なります。
また [[JSON]] を利用する[[プロトコル]]や [[Web API]] などがそれぞれで認められる名前の種類と解釈を定めていたりします。
*** 重複メンバー
[248] [[RFC 7159]] の追加部分によると、[[メンバー]]の順序を保持する実装と保持しない実装があるようです。
[49] [[RFC]] では[[オブジェクト]]内で名前は固有である[['''べき''']] [SRC[>>3 2.2., [[RFC 7159]]]]
とされていますが、 [[ECMA-404]] ではそのような制限はありません。
[[ECMAScript]] 仕様書で定義される [[JSON]] から [[JavaScript]] への変換では、
同名の[[メンバー]]のうち最後のものが [[JavaScript]] [[オブジェクト]]に反映されます。
[223] 同名の[[メンバー]]に対する処理が定義されていないため、実装によりどの値を選択するかが異なり、
[[セキュリティー]]上問題となる危険性もあります。
[247] [[RFC 7159]] の追加部分によると、重複の内最後を選択する実装の他、エラーとなる実装やすべてを返す実装もあるようです。
[224] しばしば[[注釈]]として他の正規の[[メンバー]]と衝突しない名前を採用する慣習が一部にあり、
同名の[[メンバー]]があってもエラーにはならないことを仮定して複数の同名の[[メンバー]]によって複数の[[注釈]]を表すことがあるようです。
[287] [[OAuth 2.0]] は重複した指定を禁止しているようです。
;; [[トークンエンドポイント]]参照。
** 配列
[50] [[配列]]は、 [CODE(char)[[['''[''']]]] の後に0個[[以上]]の値を [CODE(char)[[[,]]]]
で区切って並べ、最後に [CODE(char)[[[''']''']]]] が来る文字列として表されます。 [SRC[>>132, >>3 2.3.]]
[232] 値の個数に上限はありません。
[51] 最後の値の次に [CODE(char)[[[,]]]] を入れることは認められていません。
値なしに [CODE(char)[[[,]]]] が連続することも認められていません。
[FIG(railroad)[
= [CODE[ [ ]]
= ?
== [[JSON値]]
== *
=== [CODE[[[,]]]]
=== [[JSON値]]
= [CODE[ ] ]]
]FIG]
[231] [[配列]]がどう解釈されるのか、順序に意味があるという以上には定義されていません。
一般的には各種[[プログラミング言語]]の[[配列]]に対応付けられています。
[233] 値について、すべて同じ種類の値でなければならないなどの制約はありませんが、
[[JSON]] を利用する[[プロトコル]]その他によっては値の種類や可能な値に制約があるかもしれません。
** 数値
[53] [[数値]]は、必要なら[[負符号]]の後、[[整数部]]が来て、
必要なら[[小数部]]が来て、最後に必要なら([[十]]の)[[指数部]]が来る形を取ります。
[SRC[>>132, >>3 2.4.]]
[FIG[
- number = ["-"] int ["." 1*DIGIT] [ exp ]
- int = "0" / ( (DIGIT - "0") *DIGIT )
- exp = "e" ["-" / "+"] 1*DIGIT
]FIG]
[54] 先頭に[[正符号]]を使うことは認められていません。[[指数部]]では使えます。
[FIG(railroad)[
= ?
== [CODE[[[-]]]]
= |
== [CODE[[[0]]]]
== =
=== [CODE[[[1]]]]-[CODE[[[9]]]]
=== *
==== [CODE[[[0]]]]-[CODE[[[9]]]]
= ?
== [CODE[[[.]]]]
== +
=== [CODE[[[0]]]]-[CODE[[[9]]]]
= ?
== |
=== [CODE[[[E]]]]
=== [CODE[[[e]]]]
== |
=== [CODE[[[-]]]]
=== [CODE[[[+]]]]
== +
=== [CODE[[[0]]]]-[CODE[[[9]]]]
]FIG]
[234] [[符号]]の意味は自明であるためか、明確には規定されていません。
「先頭には[[負符号]] [CODE[-]] を置くことができる」 [SRC[>>132]] との規定より、 [CODE[-]]
で始まるなら残りの部分で表される[[数値]]が[[絶対値]]であるような[[負数]]、
そうでなければ[[正数]]を表すと解釈するのが自然でしょう。
[[指数部]]では更に [CODE[+]] も置くことができ [SRC[>>132]]、
残りの部分で表される[[数値]]が[[絶対値]]であるような[[正数]]と解釈するのが自然でしょう。
[308] [CODE[0]] と [CODE[-0]] の違いの扱いは、明記されていません。
構文上は [CODE[-0]] などの形で[[負]]の [[0]] を記述することは可能です。
[[JSON]] 仕様としては規定せず[[応用]]に委ねているのでしょう。
実際にはほとんどすべての場合に [CODE[-0]] は単に[[0]] であるとして扱われ、
[[-0]] とはみなされません。両者の違いに意味を持たせた用法は[[相互運用性]]が高くありません。
[EG[
[309] [[JSON]] への変換は [[-0]] を [CODE[-0]] と出力するかもしれませんが、
[[JSON]] からの変換が [CODE[-0]] を [[+0]] と解釈するかもしれません。
]EG]
[EG[
[335] 逆に [[JavaScript]] の [CODE(JS)@en[[[JSON.parse]]]] は [CODE[-0]] を [[-0]]
と解釈しますが、 [CODE(JS)@en[[[JSON.stringify]]]] は [CODE(JS)@en[JSON.parse ("-0")]]
の結果を与えると [CODE[0]] と出力します。
]EG]
[55] [[十進数]]により表記します [SRC[>>132, [[RFC 7159]]]]。
[56] [[整数部]]で[[先導0]]は認められていません [SRC[>>132]]。
[[指数部]]では使えます。
;; [243] [[先導0]]が排除されているのは、[[JavaScript]] において[[八進数]]と解釈されるからです。
[305] [[小数部]]を含めることができます [SRC[>>132]]。[[小数点]]は [CODE[[[.]]]]
です [SRC[>>132]]。[[小数点]]のみ含めて[[小数部]]を何も含めないことは認められていません。
末尾が [CODE[0]] であっても構いません。
[235] 表現できる数値の最小や最大、精度は規定されていません。 [[JSON]]
を利用する[[プロトコル]]その他や実装する[[プログラミング言語]]によっては制限や限界があるかもしれません。
[306] [[小数部]]の末尾に [CODE[0]] が余分にある場合とない場合とで値の解釈に相違があるかどうかは明記されていません。
[[JSON]] 仕様としては規定せず[[応用]]に委ねているのでしょう。
実際にはほとんどすべての場合に[[小数部]]の桁数は意味を持たず、
末尾の [CODE[0]] の有無や [CODE[0]] のみの[[小数部]]の有無は、意味を持ちません。
意味を持たせた用法は[[相互運用性]]が高くありません。
;; [307] [[プログラミング言語]]によっては[[小数部]]が含まれれば[[実数]]、
含まれなければ[[整数]]と区別することがありますが、 [[JSON]] にはそのような違いはありません。
もっとも、[[プログラミング言語]]の [[JSON]] の実装によっては [[JSON]]
からの変換時にこの違いから[[データ型]]を決めたり、
[[JSON]] への変換時に[[データ型]]により桁数を決めたりするかもしれません。
[249] [[RFC 7159]] は次のような追加の規定を設けています。 [[IEEE 754]]-2008 [[binary64]]
([[倍精度]]) 数が広く実装されておりますので、その範囲・精度で [[JSON]]
数を実装すると[[相互運用性]]が高くなります。その範囲外の [[JSON]] 数を使うと[[相互運用性]]の問題が生じるかもしれません。
[EG[
[284] 64ビット整数を扱える環境で出力した数値は、 [[JavaScript]] の数値に変換される際に[[浮動小数点数]]に変換され、元の値と近くても異なる値に変わってしまうことがあるので、注意が必要です。
]EG]
[57] [[無限大]]や[[NaN]]は表現できません。 [SRC[>>132, >>3 2.4.]]
[310] 次のような場合は、 [[JSON]] [[数値]]ではなく、[[文字列]]として扱う方が安心です。
[FIG(list)[
- [[桁数]]に意味がある場合 (例えば[[小数部]]の[[桁数]]で[[精度]]を表す場合)
- [[符号付き32ビット整数]]の範囲外の[[整数]]を正確に扱いたいとき
- [[倍精度浮動小数点数]]で表現できない[[数]]を扱いたいとき
- [[無限大]]を扱いたいとき
- [[NaN]] を扱いたいとき
- [[-0]] を扱いたいとき
- [[数字列]]であって[[数値]]でないとき (例えば[[電話番号]])
]FIG]
** 文字列
[58] [[文字列]]は、0個以上の[[文字]]を[[引用符]]で括ることによって表されます
[SRC[>>132, >>3 2.5.]]。
[236] ただしここでいう[[文字]]は、厳密には [[Unicode符号位置]]であり、以降でも同様です。
これについては >>216 を参照してください。
[237] [[文字列]]は[[JSON値]]の一種として、または[[オブジェクト]]の[[名前]]の部分として用いられます。
[59] [[文字]] (厳密には[[符号位置]]) は [[escape]] により表現することができます。特に [CODE(char)[[["]]]],
[CODE(char)[[[\]]]], [CODE(char)[[[U+0000]]]] - [CODE(char)[[[U+001F]]]]
については必ず [[escape]] しなければなりません。
[SRC[>>132, >>3 2.5.]]
[65] [[escape]] とそれによって表される[[文字]]の対応関係は次の表の通りです。
[FIG(list)[
,* [[JSON]] 表記,* [[文字]]
,[CODE(JS)[\"]],[CODE(char)[[["]]]]
,[CODE(JS)[\\]],[CODE(char)[[[\]]]]
,[CODE(JS)[\/]],[CODE(char)[[[/]]]]
,[CODE(JS)[\b]],[CODE(char)[[[U+0008]]]]
,[CODE(JS)[\f]],[CODE(char)[[[U+000C]]]]
,[CODE(JS)[\n]],[CODE(char)[[[U+000A]]]]
,[CODE(JS)[\r]],[CODE(char)[[[U+000D]]]]
,[CODE(JS)[\t]],[CODE(char)[[[U+0009]]]]
,[CODE(JS)[\u[VAR[HHHH]]]],[CODE(char)[U+[VAR[HHHH]]]]
]FIG]
[66] [[escape]] 内の[[大文字]]と[[小文字]]は一般に区別されます。
しかし[[十六進数]]は[[大文字]]でも[[小文字]]でも構いません。 [SRC[>>132, >>3 2.5.]]
[60] [CODE(char)[[[U+10000]]]] [[以上]]の[[文字]]は [[UTF-16]]
[[サロゲート・ペア]]の2つの[[16ビット符号単位]]の列によって [[escape]]
で表せます。 [SRC[>>132, >>3 2.5.]]
[238] [[16進数]]はなぜか [[Unicode]] ではなく [[ISO/IEC 10646]]:2012 により解釈する [SRC[>>132]]
とされています。しかし実用上は [[Unicode]] の任意の版と理解して構わないでしょう。
[64] [[サロゲート]]や[[非文字]]の[[符号位置]]を使うことは禁止されていません。
[61] 明記されていませんが、半分は[[サロゲート・ペア]]の[[符号位置]]そのまま、
もう半分は [[escape]] というような列で [CODE(char)[[[U+10000]]]]
より大きな[[文字]]を表現することは認められていないと解釈できます。
;; [115] [[ES5]] の [[JSON]] の構文と構文解析の定義上は、 [[ECMAScript]] の [[UnicodeEscape]]
と同じとなっており、従って[[サロゲート・ペア]]の[[符号位置]]も単なる[[16ビット符号単位]]の文字列表現として普通に解釈されるべきものであるようです。
;; [116] [[Perl]] モジュール [CODE(perl)[[[JSON::XS]]]] はそのような[[サロゲート・ペア]]の[[符号位置]]に遭遇するとエラーを出して構文解析を中止します。
[239] [[文字]]の数に上下限はありません。[[文字列]]は[[空文字列]]であっても構いません。
[FIG(railroad)[
= [CODE[[["]]]]
= *
== |
=== [CODE[\]]、[[C0]] 以外の[[文字]]
=== =
==== [CODE[[[\]]]]
==== |
===== [CODE[[["]]]]
===== [CODE[[[\]]]]
===== [CODE[[[/]]]]
===== [CODE[[[b]]]]
===== [CODE[[[f]]]]
===== [CODE[[[n]]]]
===== [CODE[[[r]]]]
===== [CODE[[[t]]]]
===== =
====== [CODE[[[u]]]]
====== 4[[十六進数字]]
= [CODE[[["]]]]
]FIG]
[240] [[JSON]] を利用する[[プロトコル]]等によっては、[[文字]]の数やどのような[[文字列]]が認められるかに制限があるかもしれません。
** boolean
[67] [CODE(JS)[[[true]]]] や [CODE(JS)[[[false]]]] の意味は >>132 では定義されていませんが、それぞれ [[boolean]]
の[[真]]と[[偽]]を表すと理解されています。これらは[[小文字]]でなければなりません。
** null
[68] [CODE(JS)[[[null]]]] の意味は >>132 では定義されていませんが、 [[null]] を表すと理解されています。
これは[[小文字]]でなければなりません。
** バイナリー
[213] [[JSON]] には[[バイナリーデータ]]を表現する方法がありません。[[文字]]の列は[[文字列]]として表現できますが、
[[バイト]]の列を [[JSON]] に直接含めることはできません。
[214] [[文字]]と[[バイト]]の区別が無いか曖昧な[[言語]]や環境では[[文字列]]が[[バイト列]]として使われることもありますが、
厳密にはそのような用法は [[JSON]] ではありません。
[215] [[バイト列]]その他の[[バイナリーデータ]]を扱いたい時は、 [[MessagePack]] など[[バイナリーデータ]]を扱えるデータ形式を使うか、
[[Base64]] など[[バイト列]]を[[文字列]]に符号化する方法を使って [[JSON]] の[[文字列]]に埋め込むなどする必要があります。
* 構文
[101] [DFN[[[JSON]] [RUBYB[テキスト]@en[text]]]]とは、[[JSON値]]1つです [SRC[>>132]]。
なお [[ECMAScript]] の仕様上はこれは [DFN[[CODE[[[JSONText]]]]]] と呼ばれています [SRC[>>36 15.12]]。
[HISTORY[
[47] [[RFC 4627]] は [[JSONテキスト]]を[[オブジェクト]]または[[配列]]を1つ[[直列化]]したもの
[SRC[>>3 2.]] と定義しており、[[文字列]]や[[数値]]や [[true]] や [[false]] や [[null]] のような値は認めていませんでした。
これは [[RFC 7159]] で改められていて、現在では [[RFC]] でも >>101 の定義に揃えられています。
[[IETF]] の立場からはこれは厳密には非互換変更になります。
]HISTORY]
[228] [[空文字列]]は [[JSONテキスト]]ではありません。
** 字句解析
[46] [[JSONテキスト]]は、次の[[字句]]により構成されます [SRC[>>132, >>3 2.]]。
[FIG(list)[
- [RUBYB[構造的文字]@en[structual character]]
-- [CODE(char)[[['''[''']]]], [CODE(char)[[[''']''']]]], [CODE(char)[[[{]]]],
[CODE(char)[[[}]]]], [CODE(char)[[[:]]]], [CODE(char)[[[,]]]]
-- 前後に[[空白]]があっても構いません。
-- [[空白]]は、0[[文字]][[以上]]の [CODE(char)[[[U+0009]]]], [CODE(char)[[[U+000A]]]],
[CODE(char)[[[U+000D]]]], [CODE(char)[[[U+0020]]]] です。
- JSON [RUBYB[値]@en[value]]
-- [[文字列]]
-- [[数値]]
-- [[リテラル名]]
--- [CODE(char)[[[true]]]], [CODE(char)[[[false]]]], [CODE(char)[[[null]]]]
--- [[小文字]]でなければ[['''なりません''']]。
]FIG]
[245] 多くの[[プログラミング言語]]などと異なり、 [[JSON]] には[[注釈]]がありません。
** 符号化文字集合とサロゲート
[216] [[JSONテキスト]]は、[[Unicode符号位置]]の列として定義されています [SRC[>>132]]。
;; [217] [[ECMA-404]] は [[Unicode 6.2.0]] を引用していますが、実用上は任意の版の [[Unicode Standard]]
と解釈して構わないでしょう。
[229] [[Unicode文字]]ではなく[[Unicode符号位置]]の列ですから、[[サロゲート]]の[[符号位置]]も含まれます。
[HISTORY[
[230] [[ES5]] の [[JSON]] は、 [[BNF]] により [[SourceCharacter]]、すなわち [[UTF-16]]
の[[16ビット符号単位]]について定義していました [SRC[>>36 15.12]]。この定義では、
[[サロゲート]]が正しく2つ連続する場合に[[サロゲート]]の[[符号位置]]が2つ分と解釈されるのではなく、
[[文字]]が1つと解釈されるので、厳密には >>216 の定義と違うことになりますが、
実用上は同じと言っても構わないでしょう。
[100] [[RFC 4627]] の [[JSON]] は[[文字]]の列として定義されていました。 [[RFC 7159]]
は [[Unicode文字]]の列であるとより明確に述べています。従って[[サロゲート]]は認められていません。
ただし [[ABNF]] 構文および [[escape]] の定義で[[サロゲート]]は除外されていません。
それらの意味は、 [[escape]] された[[サロゲート]]2つ分として使われる場合を除き、明確に定義されていません。
[[RFC 7159]] は実装により扱いが異なり、エラーになることもあると述べています。
]HISTORY]
;; [242] この[[サロゲート]]の扱いが問題となるのは、[[文字列]]の中だけです。 [[JSON]] として構文的に正しいテキストで[[サロゲート]]を含み得るのは[[文字列]]だけです。
[241] [[非文字]]の[[符号位置]]も禁止はされていません。
** 文字符号化方式
[218] [[JSON]] としてはこの [[Unicode符号位置]]の列をどのような[[文字符号化方式]]で表現するかまでは規定していません。
多くのプロトコルでは [[UTF-8]] の[[バイト列]]として転送されます。
[[JavaScript]] では [[UTF-16スカラー値]]の列である[[文字列]]として表現されます。
場合によっては[[シフトJIS]] や [[ISO-8859-1]] など旧来の[[文字符号化方式]]が使われます。
[HISTORY[
[69] [[RFC]] の [[JSON]] は更に[[文字符号化]]の制約があります。
[[RFC 4627]] では、 [[Unicode]] で[[符号化]]しなければ[['''ならない''']] [SRC[>>3 3.]]
とされていました。 [[RFC 7159]] では更に制約され、 [[UTF-8]]、[[UTF-16]]、[[UTF-32]]
で符号化しなければ[['''ならない''']]とされています。
[[RFC 4627]] にも [[UTF-8]]、[[UTF-16]]、[[UTF-32]] を使って構わないという記述はありましたが [SRC[>>3 6.]]、
それ以外を使ってはいけないとは明確に規定されていませんでした。
[71] [[既定]]の[[符号化]]は [[UTF-8]] です [SRC[>>3 3.]]。 [[RFC 4627]] ではこの「既定」
が何を表すのかは明記されていませんでした。特に意図がなければ [[UTF-8]]
を使うべきであるということとも、[[文字符号化方式]]が特定できないときに
[[UTF-8]] として解釈するべきということとも解釈できましたし、それ以外の解釈もあり得ました。
[[RFC 7159]] では [[UTF-16]] と [[UTF-32]] に対応していない実装があり、 [[UTF-8]]
が最も[[相互運用性]]が高いという記述が追加されています。
[75] 実装はこれらの[[符号化方式]]のいずれ、あるいはすべてに対応しなければならないのか、
しなくてもよいのか、といったことは [[RFC 4627]] ではまったく規定されておらず、
[[RFC 7159]] でも明記はされていませんが、 [[UTF-8]] は実装しなければならず、
[[UTF-16]] と [[UTF-32]] はオプションであると解釈するのが妥当でしょう。
;; [251] そんなことで[[相互運用性]]はいいのでしょうか。
* Sniffing
[72] [[RFC 4627]] の規定していた [[JSONテキスト]]は、最初の2文字が必ず [[ASCII文字]]となります。
そのため、最初の4つの[[オクテット]]のパターンにより、
,[CODE[00 00 00 [VAR[xx]]]],[[UTF-32BE]]
,[CODE[00 [VAR[xx]] 00 [VAR[xx]]]],[[UTF-16BE]]
,[CODE[[VAR[xx]] 00 00 00]],[[UTF-32LE]]
,[CODE[[VAR[xx]] 00 [VAR[xx]] 00]],[[UTF-16LE]]
,[CODE[[VAR[xx]] [VAR[xx]] [VAR[xx]] [VAR[xx]]]],[[UTF-8]]
... と区別できるとされています。 [SRC[>>3 3.]] [VAR[xx]] は [CODE[00]]
以外の[[オクテット]]を表すのでしょう。 [[JSONテキスト]]に直接 [CODE(char)[[[U+0000]]]]
が出現することは無いとされているので、 [CODE[00]] かどうかで確実に判定できます。
[73] 一般の [[JSON]] は2文字目が必ずしも [[ASCII文字]]であるとは限りません (1文字以上の[[文字列]]や1文字だけの[[数]]の場合。) が、
それでもやはり同様にこれら5つの[[文字符号化方式]]を区別できます。
[76] この [[sniffing]] は、実装が必ず使わなければならないなどという規定は特にありません。
しかし [CODE(MIME)@en[[[application/json]]]] には [CODE(MIME)@en[[[charset]]]]
[[引数]]がありませんし、実際にこれらの[[文字符号化]]が使われているのであれば、
これ、あるいはこれに類する [[sniffing]] を実装する以外に選択肢はありません。
[253] [[RFC 7159]] では [[sniffing]] の項は削除されています。
[254] なお [[ECMA-404]] は[[文字符号化]]に関して規定していないので、 [[sniffing]]
への言及もありません。
[255] このような [[sniffing]] が実際に行われているのかは不明です。例えば [[XHR]]
は使っていません。
[285] また [[UTF-32]] は[[セキュリティー]]上好ましくないと現在では考えられています。
]HISTORY]
** BOM
[160] [[ECMA-404]] は [[BOM]] を使っても良いかどうか明記していません。ただし [[ECMA-404]]
は[[文字符号化]]については触れずに[[Unicode符号位置]]の列について定義しているに過ぎないので、
別の[[層]]の[[直交]]する問題 (つまり [[JSON]] を利用するプロトコルその他に依存する)
と解するべきだと思われます。
[HISTORY[
[74] [[RFC 4627]] は [[BOM]] について言及していませんでした。 [[BOM]] がある場合は >>72 のパターンに当てはまらず、
[[UTF-16]] や [[UTF-32]] であっても [[UTF-8]] と判定されてしまいます。ただし [[RFC]]
のこの部分は単なる事実の記述であって、そう解釈[[しなければならない]]などと規定されているわけではなく、
また明確に [[BOM]] を使用しては[[ならない]]と規定されているわけでもありませんから、
どう理解するべきか難しいところです。[[RFC 4627]] の改訂にあたっても [[BOM]]
が認められているかどうかは議論になっていました。
[159] [[RFC 7159]] は [[JSON]] を生成するときに [[BOM]] を含めては[['''ならず''']]、
[[JSON]] を解釈するときに [[BOM]] を無視しても[['''構わない''']]としています。
;; [250] [[BOM]] が含まれていると [[JSON]] でないとしてエラーとみなす実装も認めています。
そんなことで[[相互運用性]]はいいのでしょうか。
;; [252] なお [[ZWNBSP]] ([[BOM]] と同じ [[U+FEFF]]) は[[文字列]]以外で現れることはありませんから、
[[BOM]] かどうかは明確に判断できます。
]HISTORY]
[161] [[XHR]] は [[JSON]] の解釈の際に [[BOM]] があれば無視するよう規定しています。
;; [317] >>74 の通り [[RFC 4627]] で [[BOM]] の扱いが明記されていなかったことから、
[[XHR]] が [[JSON]] の変種を規定しているとみなす人もいます。
しかし [[UTF-8]] の [[JSON]] と [[UTF-16]] の [[JSON]] は異なると主張するようなものですから、
「異なる [[JSON]] の処理方法がある」ならまだしも、
「[[JSON]] の異なる定義がある」と解するのは無茶でしょう。
** NULL
[341] [[JSON]] の構文上は [CODE(char)@en[[[U+0000]]]] [CODE(charname)@en[[[NULL]]]]
は認められていません。どう処理するべきかは [[JSON]] 本体仕様は規定していないので、
実装依存ということになります。
[342] [[HTML]] や [[CSS]] のような [[Web]] の各種言語に [CODE(char)@en[[[U+0000]]]]
が含まれていると、(文脈に依存して) [CODE(char)[[[U+FFFD]]]] に置き換えられたり、
除去されたりします。
[343] つまり、 [[JSON]] の[[バイト列]]を受信し、[[文字列]]に変換し、
更に [[JSON]] として解釈した場合と、[[バイト列]]を [[HTML]]
として解釈し、その一部分を取り出し、その[[文字列]]を [[JSON]]
として解釈した場合で、含まれている [CODE(char)[[[U+0000]]]]
の解釈が変わってしまうことがあります。
;; [344] [[JSON]] ファイルへの [[navigate]]
で[[テキストファイルのDOM構築]]が行われた結果を [[JSON]] として解釈する場合も、
[[HTML]] に埋め込まれた場合同様となります。
** 構文解析器
[256] [[ECMA-404]] は構文を定めるのみで、構文解析の方法は定義していません。
[[JSON]] の利用側 (例えば [[ECMAScript]]) で定義するのが適当と考えているのでしょう。
[77] [[RFC]] の定義する[DFN[JSON [RUBYB[構文解析器]@en[parser]]]]は、 [[JSONテキスト]]を他の表現に変形するものです
[SRC[>>3 4., [[RFC 7159]]]]。
[78] [[JSON構文解析器]]は、 [[JSON]] の文法に適合するすべての[[テキスト]]を[[受理]]しなければ[['''なりません''']]
[SRC[>>3 4., [[RFC 7159]]]]。
[79] [[JSON構文解析器]]は、 [[JSON]] ではない形式や拡張を[[受理]]しても[['''構いません''']]
[SRC[>>3 4., [[RFC 7159]]]]。
[80] [[受理]]する[[テキスト]]の[[サイズ]]を制限して構いません [SRC[>>3 4., [[RFC 7159]]]]。
[81] [[入れ子]]の深さを制限して構いません [SRC[>>3 4., [[RFC 7159]]]]。
[82] [[数値]]の範囲を制限して構いません [SRC[>>3 4., [[RFC 7159]]]]。
[83] [[文字列]]の[[長さ]]や[[文字]]の[[内容]]を制限して構いません [SRC[>>3 4., [[RFC 7159]]]]。
;; [84] これらの制限に抵触する場合にどのように処理しなければならないかは規定されていません。
また、 >>83 の文字の内容の制限というのが具体的に何を指しているかは不明確です。
特定の種類の文字から構成される文字列以外を処理できなくても構わないといったことでしょうか。
[102] [[ES5]] の [CODE(JS)[[[JSON.parse]]]] は、 >>79 の拡張は認めておらず、
[[ES5]] の規定に厳密に従って構文解析しなければなりません [SRC[>>36 15.12]]。
** 生成器
[257] [[ECMA-404]] は [[JSON]] の構文を定義するのみで、その生成の方法は定義していません。
[[プログラミング言語]]等の概念と [[JSON]] との対応関係は [[JSON]]
の定義するところではなくそれぞれで定めるべきと考えているため、
構文は定義できても、その構文に従う文字列をどのように生成するかは定義できないのでしょう。
[HISTORY[
[85] [[RFC]] の定義する [DFN[JSON [RUBYB[生成器]@en[generator]]]]は、 [[JSONテキスト]]を生産するものです
[SRC[>>3 5., [[RFC 7159]]]]。
[86] [[JSON生成器]]が生産する[[テキスト]]は、[[JSON]] の[[文法]]に厳密に[[適合]]しなければ[['''なりません''']]
[SRC[>>3 5., [[RFC 7159]]]]。
;; [318] [[RFC]] は自身の定義に違反するものを受理することを認めていますが (>>79)、
違反するものを生成することは認めていないのです。
つまり [[IETF]] の伝統である[[Postelの法則]]です。
]HISTORY]
[103] [[ES5]] の [CODE(JS)@[[[JSON.stringify]]]] は、 [[RFC]] ではなく [[ES5]]
の規定に従って [[JSON]] を生成しなければなりません [SRC[>>36 15.12]]。
* JSON の変種
[258] [[RFC]] が拡張された [[JSON]] に対応することを認めていることもあり、また [[JSON]]
が広い分野で用いられていることもあり、いろいろな [[JSON]] の変種が「[[JSON]]」
と呼ばれていることがあります。
[FIG(list)[
- [22] [[JSONP]] が [[JSON]] として扱われることがあります。
- [295] [[改行区切りJSON列]]その他の [[JSON]] ストリームが [[JSON]] として扱われることがあります。
- [23] [[オブジェクト]]の[[特性名]]を表す[[文字列リテラル]]が [CODE(char)[[["]]]] で括られないことがあります。
- [24] [[JSON]] の前に「[CODE(JS)[[[var]] name = ]]」のような[[文字列]]がつくことがあります。
- [25] [[YAML]] の [[serializer]] によって実際には [[JSON]] ではない [[YAML]] が [[JSON]] であるとして出力されることがあります (>>176)。
- [87] [[JavaScript]] の[[注釈]]が含まれることがあります。
-- /* ... */
-- // ...
- [88] [[配列]]や[[オブジェクト]]の最後の[[メンバー]]の後に [CODE(char)[[[,]]]] が余分に挿入されることがあります。
- [110] 果ては[[関数リテラル]]が含まれることすらあります。
- [112] # ... のような注釈が使われることがあります。
- [117] 0x0000 のような数値の16進数表記が用いられることがあります。
- [158] [[XSSI]] 防止のために本来の [[JSON]] データの前に「[CODE[)]}]]」のようなごみを挿入することがあります。
[[Source Map]] はこれを明示的に認めています。
- [165] [[Perl]] モジュールである [CODE(perl)@en[[[JSON::XS]]]] は、[[符号化]]時に数値としての [[inf]] や [[nan]] が与えられると[[引用符]]のない
[CODE[inf]] や [CODE[nan]] を出力します。 ([[復号]]はできず構文エラーになります。) [TIME[2014-01-09T11:35:59.600Z]]
- [290] [[Perlモジュール]]である [CODE(perl)@en[[[JSON::XS]]]] は [[tagged value]]
と称して [[Perlモジュール]]との対応付け情報が含まれた値を記述する構文を導入しています。
(ただし標準では無効になっています。)
-- [CITE[JSON::XS]] ([TIME[2015-02-21 19:32:42 +09:00]] 版) <http://pod.tst.eu/http://cvs.schmorp.de/JSON-XS/XS.pm#OBJECT_SERIALISATION>
-- [CITE[JSON::XS]] ([TIME[2015-02-21 19:33:08 +09:00]] 版) <http://pod.tst.eu/http://cvs.schmorp.de/JSON-XS/XS.pm#TAGGED_VALUE_SYNTAX_AND_STANDARD_JSO>
]FIG]
[267] [[JSON]] と互換性のあるもの、ないもの、 [[JSON]] 自体で表現できないデータモデルを
[[JSON]] として表現する方法を定義するもの、 [[JSON]] に触発されただけで実際には [[JSON]]
と関係性が薄いもの、[[JSON]] の[[プロファイル]]も含め、次のような名前がついた [[JSON]] の派生仕様が存在しています。
[FIG(short list)[
- [[BSON]]
- [[B-JSON]]
- [[I-JSON]]
- [[JSON-B]]
- [[JSON-C]]
- [[JSON+C]]
- [[JSON-D]]
- [[JSON-L]]
- [[JSON5]]
- [[Smile]]
- [[Universal Binary JSON]] ([[UBJSON]])
- [[JSYNC]]
- [[MongoDB Extended JSON]]
- [[JSONx]]
- [[XJSON]]
- [[PSON]]
- [[Jsonnet]]
- [[hjson]]
- [[EXI for JSON]]
- [[JCR]]
]FIG]
[286] [[CBOR]] は [[JSON]] データモデルとの互換性を大きな特徴として挙げています。
;; [268] いずれも [[JSON]] ほどの支持は集められておらず、提案段階にとどまっているか、
特定の実装にだけ採用されているものです。
[21] [[MessagePack]] は [[JSON]] の派生仕様ではなく互換性はありませんが、
「It's like JSON. but fast and small.」と謳っています。各言語のライブラリーが存在し、
それなりに広く利用されているようですが、 [[JSON]] ほどとは言えなそうですし、
対象分野も必ずしも近いとは言えなそうです。少なくても [[Web API]] 等の[[疎結合]]な [[API]]
を通じた情報交換目的で [[MessagePack]] が [[JSON]] と競合しているようには見えません。
* JSON ストリーム
[294] 複数の [[JSON]] 値の連続を表すデータ形式も幾つか存在しています。
[FIG(short list)[
- [[Concatenated JSON]]
- [[改行区切りJSON列]] ([[LDJSON]], [[NDJSON]], [[JSON Lines]])
- [[JSON text sequences]]
]FIG]
;; [292] バリエーションについても各項を参照。
[301] [[i3bar]] は、無限に長い (閉じない) [[配列]]を使っています [SRC[>>300]]。
[FIG(quote)[
[FIGCAPTION[
[300] [CITE[i3: i3bar input protocol]]
([TIME[2015-05-20 16:29:15 +09:00]] 版)
<http://i3wm.org/docs/i3bar-protocol.html>
]FIGCAPTION]
> What follows is an infinite array (so it should be parsed by a streaming JSON parser, but as described above you can go for a simpler solution), whose elements are one array per status line.
]FIG]
* JavaScript との互換性
[105] [[JavaScript]] の[[文字列リテラル]]では [CODE(char)[[[U+2028]]]] や [CODE(char)[[[U+2029]]]]
を直接記述することは認められていませんが、 [[JSON]] では認められています
[SRC[>>36 15.12.2]]。
[REFS[
- [28] [CITE[JSON: The JavaScript subset that isn't — Timeless]]
([TIME[2011-05-16 04:05:34 +09:00]] 版)
<http://timelessrepo.com/json-isnt-a-javascript-subset>
- [27] [CITE[JSON::XS - search.cpan.org]] ([TIME[2011-04-15 12:50:01 +09:00]] 版) <http://search.cpan.org/dist/JSON-XS/XS.pm#JSON_and_ECMAscript>
]REFS]
[FIG(quote)[
[FIGCAPTION[
[119] >>27 より
]FIGCAPTION]
>One of the problems is that U+2028 and U+2029 are valid characters inside JSON strings, but are not allowed in ECMAscript string literals
>Another problem is that some javascript implementations reserve some property names for their own purposes (which probably makes them non-ECMAscript-compliant). For example, Iceweasel reserves the __proto__ property name for it's own purposes.
]FIG]
[118] また、 [CODE(JS)@en[[[__proto__]]]] のように [[JavaScript]] 自体の持つ機能の名前と衝突した場合に、
[[JSON]] を直接 [[JavaScript]] と解釈すると問題が起こり得ることも指摘されています (>>119)。
[120] このような [[JavaScript]] との非互換性は、 [CODE(JS)@en[[[JSON]]]] [[オブジェクト]]のような正規の実装に依らず、
[CODE(JS)@en[[[eval]]]] などで [[JavaScript]] 文字列として解釈する際に発症します。しかも通常は
[CODE(char)@en[[[U+2028]]]] などは使わない[[文字]]なので気づきにくく、時にサービス拒否攻撃のように悪用されることもあります。
[121] また、 [[JSON]] を[[関数]]で括った“だけ”であるはずの [[JSONP]] も、
[WEAK[([[JavaScript]] と解釈されるのが目的のものですから、 [[JavaScript]] コードであることになり、)]]
実は [[JSON]] とは非互換であることになります。
* YAML との互換性
[176] [[Perl]] コミュニティーの一部など、 [[JSON]] 以前に [[YAML]] が広く用いられていた人達の中には、
[[JSON]] は [[YAML]] の[[部分集合]]であるとして、 [[YAML]] の実装を元にした [[JSON]]
の実装が行われていました。
[26] しかし [[JSON]] は [[YAML]] の[[部分集合]]であるとの主張は'''嘘'''とされています
[SRC[>>177]]。
[REFS[
- [177] [CITE[JSON::XS - search.cpan.org]] ([TIME[2011-04-15 12:50:01 +09:00]] 版) <http://search.cpan.org/dist/JSON-XS/XS.pm#JSON_and_YAML>
]REFS]
;; [70] 一部の人は真剣に [[YAML]] の[[部分集合]]であると主張しているようですが、
周囲からは冷ややかな目で見られています。また [[JSON]] 関係者からは相手にされていないようです。
[178] このため [[JSON]] であると称しながら実際には [[JSON]] ではない [[YAML]]
のデータが存在しています。
* データモデル
[275] [[JSON]] には、 [[XML]] に対する [[XML情報集合]]のような厳密な[[データモデル]]は存在しません。
[[JSON]] が、それを処理するシステムでどのような[[データ構造]]で表現されたり、
どのような [[API]] でアクセスされたりするかは、完全にシステム依存となっています。
[276] [[JSON]] が限られた種類の (多くの[[プログラミング言語]]に共通して存在する)
値だけを表現でき、 (多くの[[プログラミング言語]]の実装で) ネイティブな[[データ構造]]に直接自明に変換可能なことが、
[[JSON]] の利用のしやすさにつながっており、 [[XML]] や [[YAML]]
にかわって開発者に広く支持され、普及した一因でしょう。
;; [277] 例えば [[XML]] の場合、ほとんどの実装は[[要素]]や[[テキスト]]などに相当する[[オブジェクト]]とそれを操作する
[[API]] を提供していて、[[プログラミング言語]]のネイティブのデータ構造や[[アプリケーション]]独自の[[データ構造]]との相互変換は、
[[アプリケーション]]ごとに設計し実装する必要があります。また [[YAML]]
にも[[型]]など[[プログラミング言語]]によっては自明に対応付けられない機構が備わっています。
[278] 多くの実装において専用の機構が不要となっているために、
([[JSON]] を入出力形式として採用した任意の[[アプリケーション]]のデータ構造上ではなく)
純粋な [[JSON]] のデータモデル上での操作を規定しても、
[[相互運用]]可能な形で広く普及するかどうかはわかりません。
[EG[
[279] 例えば [[JSON Pointer]] のような [[JSON]] データモデル上の式言語は、
[[プログラミング言語]]ネイティブなデータ構造に変換した後だと直接適用できない、
あるいはしづらい操作が含まれているかもしれません。
]EG]
* 演算の記述
[311] [[JSON]] データに対する[[式言語]]として次のものがあります。
[FIG(short list)[
- [[JSONPath]]
- [[JSON Pointer]]
- [[JSON Reference]]
- [[XJSON]] の式
- [[jq]]
- [[Path (Falcor)]]
]FIG]
[312] しかしいずれも限定的にしか利用されていません。 [[JSON]] 利用者の間で広く共通認識として
[[JSON]] 中のデータを識別したり、それに関する演算を記述したりする方法として確立されているものは存在しないのが現状です。
* MIME 型
[89] [[JSON]] の [[MIME型]]は [DFN[[CODE(MIME)@en[[[application/json]]]]]] です [SRC[>>3 6.]]。
[90] この他 [DFN[[CODE(MIME)@en[[[*/*+json]]]]]] により [[JSON]] を使った特定の[[応用]]を表すことがあります。
;; [320] 実際にはあまり一般的ではありません。
[124] この他に [CODE(MIME)@en[[[text/json]]]] [SRC[>>331]], [CODE(MIME)@en[[[text/x-json]]]],
[CODE(MIME)@en[[[text/jaavscript]]]], [CODE(MIME)@en[[[text/x-javascript]]]],
[CODE(MIME)@en[[[application/x-javascript]]]],
[CODE(MIME)@en[[[text/plain]]]] が使われることもあります。
[333] [DFN[[RUBYB[[[JSON MIME型]]]@en[JSON MIME type]]]]は、次のものです [SRC[>>331]]。
[FIG(list short)[
- [CODE(MIME)@en[[[application/json]]]]
- [CODE(MIME)@en[[[text/json]]]]
- [CODE(MIME)@en[[[+json]]]] で終わる [[MIME型]]
]FIG]
[261] [[JSONP]] は [[JavaScript]] なので、 [CODE(MIME)@en[[[text/javascript]]]] を使うのが正しいですが、
[[JSON]] の [[MIME型]]になっていることもあります。
[319] [[LDJSON]] / [[JSON Lines]] の類は [[JSON]] そのものではないので、
それぞれに適切な [[MIME型]]を使うべきですが、 [CODE(MIME)@en[[[application/json]]]]
が使われることもあります。
[CODE(MIME)@en[application/orchestrate-export-stream+json]]
のように[[空白]]区切りの [[JSON]] で [CODE(MIME)@en[+json]]
が使われることもあります。
** CTE
[91] [[CTE]] としては、 [[UTF-8]] を使う時は [CODE(MIME)@en[[[8bit]]]]、
[[UTF-16]] や [[UTF-32]] を使う時は [CODE(MIME)@en[[[binary]]]] が適切です。 [SRC[>>3 6.]]
** 引数
[92] 公式には [CODE(MIME)@en[[[application/json]]]] には[[引数]]が定義されていません。
[147] 現実には次の[[引数]]が存在します。
[FIG(list short)[
- [CODE(MIME)@en[[[charset]]]]
- [CODE(MIME)@en[[[ieee754compatible]]]]
- [CODE(MIME)@en[[[odata]]]]
- [CODE(MIME)@en[[[odata.metadata]]]]
- [CODE(MIME)@en[[[odata.streaming]]]]
]FIG]
*** [CODE(MIME)@en[charset]] 引数
[93] たまに [CODE(MIME)@en[[[charset]]]] [[引数]]が付けられていることがあります。
[[RFC]] などの仕様書や [[Web API]] のドキュメントの類などでも、
しばしば [CODE(MIME)@en[[[charset]]]] [[引数]]が指定されています。
[125] [CODE(MIME)@en[[[charset]]]] が指定されていないと [[UTF-8]] であっても正しく[[復号]]できない実装があります。
[TIME[2013-03-06T07:46:28.900Z]]
[129] 他方、[[引数]]なしの「[CODE(MIME)@en[[[application/json]]]]」でないと [[JSON]]
が指定されたとみなさない実装もあります。
[FIG(quote)[
[FIGCAPTION[
[288] [CITE@en[REST API for MongoLab | MongoLab Documentation & Support]]
([TIME[2015-02-18 07:12:40 +09:00]] 版)
<http://docs.mongolab.com/restapi/>
]FIGCAPTION]
> The API does support UTF-8 characters. As per the HTTP spec <http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1>, you need to be sure to explicitly set the character set you are using in the Content-Type header. The default character set (ISO-8859-1) is not very i18n friendly.
]FIG]
[289] >>288 のように [CODE(MIME)@en[[[charset]]]] が [CODE(MIME)@en[[[application/json]]]]
にも適用されると [[HTTP]] を根拠に主張する実装もあるようです。
;; この解釈は [[RFC 2616]] を誤読しています。
** [CODE(MIME)@en[+json]] で終わる MIME 型
[FIG(list)[
- [98] [CODE(MIME)@en[[[application/jsonml+json]]]]
- [122] [CODE(MIME)@en[[[application/ld+json]]]]
- [99] [CODE(MIME)@en[[[application/microdata+json]]]]
]FIG]
* 拡張子
[94] [[JSON]] の[[拡張子]]には [CODE(file)@en[[[.json]]]] [SRC[>>3 6.]] がしばしば使われます。
* Macintosh ファイル型
[95] 古い [[Mac OS]] で[[ファイル]]の種類を表す[[符号]]としては [CODE[[[TEXT]]]]
が使われます [SRC[>>3 6.]]。
* 素片識別子
[96] [[RFC]] では[[素片識別子]]には言及されていません。
[97] [[JSON]] では[[素片識別子]]は使われていません。
[162] [[JSON Pointer]] というものがあり、[[JSON]] の[[素片識別子]]として使われることが想定されています。
* 歴史
[REFS[
- [3] [CITE@en[RFC 4627 - The application/json Media Type for JavaScript Object Notation (JSON)]]
<http://tools.ietf.org/html/rfc4627>
- [34] [CITE[Annotated ES5]]
-- [35] [CSECTION@en[5.1.5 The JSON Grammar]] <http://es5.github.com/#x5.1.5>
-- [36] '''[CSECTION@en[15.12 The JSON Object]] <http://es5.github.com/#x15.12>'''
]REFS]
[104] [[ES5]] は、 [[RFC]] を引用しつつも独自に構文や解釈を規定しています。
[[Webブラウザー]]は [[ES5]] を実装しており、現在ではこちらが [[JSON]] の定義として参照されるべきものでしょう。
[163] その後 [[ECMA-404]] が出版されました。 [[ES6]] は [[ECMA-404]] を参照するように改められています。
ただし [CODE(JS)@en[[[JSON]]]] オブジェクトや構文解析、直列化の方法は [[ES]] 側に残されています。
** ietf-json と ECMA-404
[194] 2013年の初め頃、 [[IETF]] において [[RFC 4627]] を改訂して[[標準化過程]] [[RFC]]
とすることを目指す動きが起こり、 [DFN[[[IETF]] JSON [RUBYB[作業部会]@en[working group]]]]
([DFN[[[ietf-json]]]]) が組織されました。細かな修正もありますが、[[Informational]] から[[標準化過程]]に移すことで、
([[IETF]] の標準化手続き上) より他の[[標準化過程]] [[RFC]] から参照しやすくすることが主たる目的だったようです。
[195] 当初は [[JSON]] の考案者で [[RFC 4627]] の著者でもある [[Douglas Crockford]]
も協力する姿勢を見せていましたが、改訂の方向性に納得がいかなかったのか、2013年の中頃には関わらないようになります。
その理由は明言していませんし、 [[ietf-json]] [[メーリングリスト]]の記事をみても議論がはっきり決裂しているわけではないのですが、
Douglas が意図的に曖昧にし (各言語・環境の) 実装に委ねている箇所を特定の解釈に固定したり、
[[部分集合]]や拡張によって非互換な[[プロファイル]]を作ろうとしたりする動きに賛成しかねているようです。
[196] 2013年の夏、 Douglas と [[ECMA]] [[TC 39]] ([[ECMAScript]] の標準化コミュニティー) は [[ES5.1]]
における [[JSON]] の定義を元にした独立した [[JSON]] の仕様書を作成し、数週間で [DFN[[[ECMA-404]]]]
として出版されました。 [[ES6]] からは [[JSON]] の定義は削除され、 [[ECMA-404]] を参照する形に改められました。
ただし [CODE(JS)@en[[[JSON]]]] オブジェクトの定義や [[ECMAScript]] との相互変換の定義は [[ES6]]
側に残されています。
[197] この ([[IETF]] では考えられないくらいに) 素早い新仕様の出版に、 [[Tim Bray]] ら [[ietf-json]]
側の関係者は [[JSON]] の標準化を行っているのは [[ietf-json]] であって [[TC 39]] では無い、
[[TC 39]] とは協力関係にあったはずなのに連絡もなかったなどと非難しますが、
[[TC 39]] 側はほとんど相手にしていません。互いの仕様の不備を主張し合うなど、両者の溝は埋まりません。
そこへ一見無関係な [[W3C]] の [[TAG]] も乱入してきて、
[[RFC]] の改訂版は [[ECMA-404]] の定義を参照するべきとするコメントを [[IETF]]
側に送付するなど、ちょっとした騒ぎになりました。
[198] 結局 [[RFC]] の改訂版は [[ECMA-404]] を参照していますが、違いを説明するために引用しているに過ぎず、
独自に [[JSON]] を定義しています。ただし [[JSON]] 全体は[[オブジェクト]]や[[配列]]だけでなく、
任意の値となるよう拡張されました ([[ECMA-404]] と同等になりました。 >>47、>>101 を参照。)
その他にも旧 [[RFC]] や [[ECMA-404]] にない規定が追加されています。更に [[JSON]]
の拡張や[[部分集合]]を定義することが引き続き [[ietf-json]] で検討されています。
こうして [[IETF]] によって [[JSON]] は [[fork]] されました。
[REFS[
- [179] [CITE[''''''[''''''Json'''''']'''''' Coordinating publication of 4627bis with ECMA]]
( ([TIME[2013-05-17 10:20:05 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/json/current/msg00267.html>
- [180] [CITE@en[charter-ietf-json-01]]
( ([TIME[2013-10-21 05:27:10 +09:00]] 版))
<https://datatracker.ietf.org/doc/charter-ietf-json/>
- [181] [CITE@en[JavaScript Object Notation (json) - Charter]]
( ([TIME[2013-10-21 05:28:37 +09:00]] 版))
<https://datatracker.ietf.org/wg/json/charter/>
- [182] [CITE[json Discussion Archive - Thread Index]]
( ([TIME[2013-10-23 18:32:14 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/json/current/threads.html>
- [183] [CITE[''''''[''''''Json'''''']'''''' Possible next work for the WG]]
( ([TIME[2013-10-16 19:21:19 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/json/current/msg01856.html>
- [184] [CITE[''''''[''''''Json'''''']'''''' Authorship]]
( ([TIME[2013-09-27 18:20:05 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/json/current/msg01623.html>
- [185] [CITE[''''''[''''''Json'''''']'''''' JSON & ECMA]]
( ([TIME[2013-03-19 21:22:04 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/json/current/msg00222.html>
- [186] [CITE[''''''[''''''Json'''''']'''''' Two Documents]]
( ([TIME[2013-06-18 14:21:41 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/json/current/msg00822.html>
- [187] [CITE[Re: ''''''[''''''Json'''''']'''''' Two Documents]]
( ([TIME[2013-06-19 14:52:20 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/json/current/msg00894.html>
- [188] [CITE[''''''[''''''Json'''''']'''''' 2-step proposal 4627bis + I-JSON]]
( ([TIME[2013-07-08 16:50:03 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/json/current/msg01145.html>
- [189] [CITE[''''''[''''''Json'''''']'''''' Consensus call: document title]]
( ([TIME[2013-06-24 16:20:15 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/json/current/msg00916.html>
- [190] [CITE[''''''[''''''Json'''''']'''''' What are we trying to do?]]
( ([TIME[2013-07-03 20:21:08 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/json/current/msg01087.html>
- [191] [CITE[Appropriate list for JSON standardization disussion]]
( ([TIME[2013-06-21 04:11:18 +09:00]] 版))
<https://mail.mozilla.org/pipermail/es-discuss/2013-June/031070.html>
- [126] ( ([TIME[2013-03-11 16:24:22 +09:00]] 版))
<http://www.ietf.org/proceedings/86/slides/slides-86-json-2.pdf>
- [127] [CITE[''''''[''''''apps-discuss'''''']'''''' JSON mailing list and BoF]]
( ([TIME[2013-02-19 20:50:03 +09:00]] 版))
<http://www.ietf.org/mail-archive/web/apps-discuss/current/msg08912.html>
- [131] [CITE@en[Next Steps on JSON + Proposed TAG Resolution]]
( ([[Appelquist Daniel (UK)]] 著, [TIME[2013-10-18 04:39:12 +09:00]] 版))
<http://lists.w3.org/Archives/Public/www-tag/2013Oct/0029.html>
- [133] [CITE@en[draft-ietf-json-rfc4627bis-04 - The JSON Data Interchange Format]]
( ([TIME[2013-10-14 08:15:24 +09:00]] 版))
<http://tools.ietf.org/html/draft-ietf-json-rfc4627bis-04>
- [134] [CITE@en[draft-ietf-json-rfc4627bis-06 - The JSON Data Interchange Format]]
( ([TIME[2013-10-16 22:34:48 +09:00]] 版))
<http://tools.ietf.org/html/draft-ietf-json-rfc4627bis-06>
- [135] [CITE@en[Re: XHR vs JSON, was: Next Steps on JSON + Proposed TAG Resolution]]