Hatena::ブログ(Diary)

yref NOTE

April 28(Wed), 2010 [perl] JSONのエンコード

JSONエンコード

とても参考になったサイト:

1.encode() 時は、ハッシュ内の全ての非 ASCII 文字列は、必ず予め utf8 フラグ ON にしておく。

2.encode() で出力される JSON 文字列の utf8 フラグは、予め utf8() メソッドで指定できる。

3.decode() 時は、入力する JSON 文字列の utf8 フラグの状態を、必ず utf8() メソッドで指定する。

4.decode() で出力されるハッシュ内の文字列の utf8 フラグの状態は、文字列の内容(ASCII/非ASCII)に依存する。

JSON モジュールの utf8 フラグ周りの仕様 tips 注意点

詳しく。。

JSON モジュールで utf8 を扱う際の注意点

  1. encode 時(ハッシュなどのPerlオブジェクトからJSONを生成)は、

入力ハッシュが日本語などの非 ASCII 文字列を含む場合は、

必ず utf8 フラグ ON (string) である必要があります。

utf8 フラグ OFF (octets) の日本語を含むハッシュを入力すると、文字化けします。

utf8 フラグ OFF (octets) の ASCII 文字のみの場合は、問題は起こりません。


  • encode 時に出力される JSON 文字列の utf8 フラグの状態は、utf8() メソッドの指定通りになります。

入力する JSON に日本語などの非 ASCII 文字列を含む場合は、

->utf8(0) してから、utf8 フラグを ON にした JSON を入力するか、または

->utf8(1) してから、utf8 フラグを OFF にした JSON を入力する必要があります。

それ以外の組み合わせでは、エラーが発生するか、文字化けします。

  • JSON->new->utf8(0)->decode($string) ⇒ OK!
  • JSON->new->utf8(1)->decode($string) ⇒ エラー!
  • JSON->new->utf8(1)->decode($octets) ⇒ OK!
  • JSON::XS->new->utf8(0)->decode($octets) ⇒ 文字化け
  • JSON::PP->new->utf8(0)->decode($octets) ⇒ 全て utf8 フラグ OFF で返ります(例外)

  • decode 時に生成される Perl オブジェクト中の文字列の utf8 フラグの状態は、
  • 文字列の内容に依存します。
  • ASCII 文字のみの文字列は、常に utf8 フラグ OFF になります。
  • ASCII 文字を含む文字列は、常に utf8 フラグ ON になります。
*


#!/usr/bin/perl

use JSON;
use Data::Dumper;


my %allList;

my $hs = {
          'ip' => '',
          'lter' => '0',
          'indate' => '2010-04-01',
          'outdate' => '0000-00-00',
          'nm_no' => '344',
          'name' => '廣中',
          'grp' => 'VM'
        };

my $hss = {
          'lter' => '0',
          'indate' => '2007-04-02',
          'name_ff' => 'てつや',
          'outdate' => '0000-00-00',
          'nm_no' => '101',
          'grp' => 'OSS'
        };

my $ldaprel = {
          'pkiflag' => '1',
          'manager' => [
                       ],
          'TelephoneNumber' => '',
          'postalCode' => ''
        };

#-- JSONに変換する前に Encode::decode_utf8 ---
$hs->{$_} = Encode::decode_utf8($hs->{$_}) foreach keys %$hs;
$hss->{$_} = Encode::decode_utf8($hss->{$_}) foreach keys %$hss;
$ldaprel->{$_} = Encode::decode_utf8($ldaprel->{$_}) foreach keys %$ldaprel;

$allList{0} = {'mysql' => $hs, 'postgres' => $hss, 'ldap' => $ldaprel};


	# print Dumper(%allList);

#-- JSONに変換 ---
my $allList_json = JSON->new->encode(\%allList);

        # print Dumper($allList_json);


#================================

#-- JSONから変換 ---
my $allList_j = JSON->new->utf8(0)->decode($allList_json);

print scalar(keys(%$allList_j));


#-- ハッシュに戻したあとに Encode::encode_utf8 ---
foreach my $keyno( keys %$allList_j){
    foreach my $keydb( keys %{$allList_j->{$keyno}}){
        my $dbeach = $allList_j->{$keyno}->{$keydb};
        $dbeach->{$_} = Encode::encode_utf8($dbeach->{$_}) foreach keys %$dbeach;
    }
}

        # print Dumper($allList_j);