読者です 読者をやめる 読者になる 読者になる

改行を含んだJSON

JSON

PerlJSON::Syckでデータに改行が含まれるオブジェクトを Dump すると、以下のような出力が得られる。

$ perl -de0
  DB<1> use JSON::Syck
  DB<2> $data = { foo => "xxx\nyyy" }
  DB<3> p JSON::Syck::Dump($data)
{"foo":"xxx\n\
yyy"}

読みやすくするためか、改行コードを \ でエスケープした形式。
JSON.pm だと改行コードは含まれない。

  DB<4> use JSON
  DB<5> p objToJson($data)
{"foo":"xxx\nyyy"}

で、JSON::Syck が出力するデータは JavaScript の eval では parse できるが、json.org の json.js や、Jemplate(0.18) 附属の Jemplate.js (に含まれる JSON function) では parse できない。

サンプルコード。
test.js

{ "foo": "bar\n\
baz" }

test.html

<script type="text/javascript" src="http://search.cpan.org/src/INGY/Jemplate-0.18/share/Jemplate.js"></script>
<script type="text/javascript" src="http://www.json.org/json.js"></script>
<script type="text/javascript">
var result = document.getElementById('result');
function useJemplate(){
  Ajax.get(
    'test.js',
    function(r) { document.getElementById('result').innerHTML = JSON.parse(r) }
  )
}
function useJsonJs(){
  Ajax.get(
    'test.js',
    function(r) { document.getElementById('result').innerHTML = r.parseJSON() }
  )
}
function useEval(){
  Ajax.get(
    'test.js',
    function(r) { document.getElementById('result').innerHTML = eval('('+ r + ')') }
  )
}
</script>
<a href="javascript:useJemplate()">use Jemplate</a><br>
<a href="javascript:useJsonJs()">use json.js</a><br>
<a href="javascript:useEval()">use eval</a><br>
<a href="test.js">test.js</a>
<div id="result" style="width: 100%; height: 300px;"></div>

use eval をクリックすると object が得られているが、use Jemplate, use json.js はどちらも false. (というか、Jemplate.js 内の JSON function は json.js の古い版だ)

json.org のトップページでは以下のような記述があって。

char
    any-Unicode-except-"-or-\-or-control
    \"
    \\
    \/
    \b
    \f
    \n
    \r
    \t
    \u four-hex-digits 

これを読む限り、改行コードを \ でエスケープ、というのは正しくない形式のような……(JavaScript の eval ではたまたま読める、けど)
[追記] RTには登録済みでした