中国語の入力/照会

企業法人が急速にグローバル展開を始めており、その中にあって Web適用業務も英語だけではなく
現地の言語への対応を迫られています。
最も代表的な近隣諸国、中でも中国語のコンテンツの入力や照会をここで紹介します。

国際言語ロケールのためのポイント

国際言語ロケールのための重要なポイントを次に示します。

  • CCSID を正しく理解する
  • HTML を UTF-8 で表現する
  • UTF-8 から各国語データ・ベースへ変換する
  • ブラウザの言語対応を理解する

■ CCSID を正しく理解する

各国言語の CCSID を把握することと CCSID に応じたデータ・ベースを作成します。
代表的な CCSID
日本 5026
5035
1399
米国   37
中国簡体字  935
中国繁体字  937
韓国  833
タイ  838
ドイツ 1011

CCSID 1399 は Unicode ではありません

都市伝説として CCSID 1399 は Unicode であるとの誤解がありますが CCSID 1399 は決して
Unicode ではありません。
Unicode では漢字は3バイト表現であり3バイトでひとつの漢字を表しますが、1399 では
EBCDIC であるので漢字はあくまで2バイト表現です。同じであるはずがありません。
CCSID 1399 は CCSID 5035 + NEC選定漢字 を加えただけです。

■ HTML を UTF-8 で表現する

日本語の HTMLの文字コードは charset=Shift_JIS のようにShift_JIS で表記することが
一般的でしたが世界的な規約としてすべての各国言語のコードが重複することのないように
規定されたUnicode (ユニコード) で表記することが一般的です。
Unicode の中でも UTF-8 と呼ばれるユニコードは漢字は 3バイト表現ですが英小文字は
Shift_JIS と同じであり半角 1バイトASCII コードで表記されます。
このため UTF-8 がユニコードとして世界中で最もポピュラーなユニコードとして普及しています。
( Yahoo! や Google のHTMLをソース表示して調べてみてください。)

■ UTF-8 から各国語データ・ベースへ変換するには

ブラウザへの出力では各国言語をすべて同じ、ひとつの UTF-8 というユニコードに
変換して表示しますが、逆に入力の場合はユニコード(UTF-8) として入力された文字を
各国の対応する言語コードに戻して変換する必要があります。
このとき、どの言語に戻すべきかを判断するために国を識別する必要があります。

[参考]入力された文字をどのように判定するのか ?

ブラウザから Webサーバーへ SUBMIT で投入された文字列が Shift_JIS であるのか、
または Unicode(UTF-8) であるのかをどのようにして判定すればよいのでしょうか ?
HTML 内部には charset=Shift_JIScharset=utf-8 とか書かれているので、
わかるのではないかと思われがちですが、実はこの情報は Webサーバーへは伝えられていません。
HTTP/1.1の仕様では、charset もサーバーに送信することになっていますが MS-IE は、
これには従っていないのです。
そこで EnterpriseServer では

  <input type="hidden" name=CHARSET value="UTF-8">

という文字列を HTML のどこかに埋め込むことによって

  CHARSET=UTF-8

という文字列がサーバーに伝わるようにしています。

■ ブラウザの言語対応を理解する

ブラウザには [ツール] - [インターネット・オプション] の 「言語」 ボタンを押すと
言語の優先順位を設定できるようになっています。
EnterpriseServer では、この一次言語によって UTF-8 で入力された国を判断します。

[参考] as400-net.com ライブラリー [解説書] - [技術解説] - [国際言語ロケールの手引き]
( http://www.officequattro.com/ESTUDIO_HELP_V60/TECHINF/TECH/TECH_LOCAL/tech_local.html )

IBM Apache HTTP サーバーとの比較

EnterpriseServer では Shift_JISUTF-8 との混在や複数多言語の同時サポートを行なうことができますが
IBM Apache HTTPサーバーでは ブラウザ側のコードはすべて同じひとつのコードでなくてはなりません。
これは入出力のコード変換を CHGHTTPA という、ひとつのコマンドだけで一意的に決定する仕組みに
なっているからです。

これに対して EnterpriseServer では HTML内部に CHARSET=UTF-8 という文字列が SUBMIT されるように
hidden (非表示) で埋め込んでおいて、さらにブラウザの一次言語が日本語以外であれば UTF-8 から
国別コードの CCSID へ変換する仕組みを持っています。
従って EnterpriseServer であれば既存の適用業務は、そままでさらに各国対応のUTF-8 コードによる
国際言語ロケールを柔軟に加えることができます。

Google の解決案

Google に文字コードを明示的に宣言して SUBMIT 投入するには

  <input type="hidden" name="ie" value="UTF-8">

という文字列を HTML に埋め込みます。
値は異なりますが EnterpriseServer と同じ方法で Google も解決しています。

中国語の入力/照会のサンプル CGI

それでは 中国語簡体字データ・ベース(CCSID=935) の照会と入力のサンプルCGI の
実行を紹介しましょう。
データの照会だけならブラウザの設定は、そのままで構いませんが中国語簡体字 を
入力するのであればブラウザの一次言語を次のように中国語簡体字に設定してから行なってください。

■ 照会サンプル
【 照会画面 】

- 何も入力せずに、そのままで「検索」ボタンを押してください。
次のように明細データが中国語簡体字で照会されます。

【 明細画面 】

- ブラウザの [表示] - [エンコード] を選択してエンコードが Unicode(UTF-8)
選択されていることを確認してください。

- ブラウザの [表示] - [ソース] によって HTML ソースを表示して
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
のように charset=utf-8 と設定され、この HTML が UTF-8 として設定されて
いることを確認してください。

- HTML のソース内部には
   <input type="hidden" name=CHARSET value="UTF-8">
という文字列が埋め込まれていることを確認してください。
これによって HTML からの入力が UTF-8 であると判断されます。

■ HTML サンプルソース
<html>
<head>
<meta http-equiv="Content-Language" content="ja">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>?好 ?京CHINESE SAMPLE</title>
<STYLE TYPE="TEXT/CSS">
BODY{margin:15px;font-size:14px;background:#fff;}
FORM{margin:0;}
H1{font-size:26px; margin:10px 0px; color:#666;}
HR{height:1px;filter: Alpha(opacity=100,finishOpacity=0,style=1,startX=90,finishX=100) Alpha(opacity=0,finishOpacity=100,style=1,startX=0,finishX=10);}
TABLE{margin:10px 3px;FONT-SIZE:14px;}
INPUT{height:24px;border:1px solid #999;padding:2px;}
.HAND{cursor:hand;filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#EEEEEE, EndColorStr=#AAAAAA);}
.CLSBTN{width:100%;text-align:center;}
/* エラー反転スタイル */
.NORMAL{border:solid 1px #666666}
.ERR_RED{border:solid 1px #666666;background-color:#ffccee}
</STYLE>
<script language="javascript">
function crtNewRecord(){
	var url = "/cgi-bin/CHS002.PGM";
	url += "&dummydate=" + new Date().getTime();

	var w_size = 500;
	var h_size = 350;
	var y_pos = Number((window.screen.height - h_size)/2);
	var x_pos = Number((window.screen.width - w_size)/2);

	window.open(url,'CHK002','width='+ w_size +',height='+ h_size +',top='+ y_pos +',left='+ x_pos +',status=no,scrollbars=no,directories=no,menubar=no,resizable=no,toolbar=no');
}
</script>
</head>
<body onLoad="chkServerError();">
<center>
<h1>?好 ?京CHINESE SAMPLE</h1>
</center>
<hr>
<form name="frmDsphead" method="POST" action="/cgi-bin/CHS001.PGM">
<INPUT TYPE="HIDDEN" NAME="CHARSET" VALUE="UTF-8">
<!-- イベントドリブン用 Hidden -->
<input type="hidden" name=ID>
<input type="hidden" name=EVENT>
<input type="hidden" name=RECORD value="DSPHEAD">
<p>項目を入力して「GO」ボタンを押してください。</p>
<KEYFROM>
<p>?好1  <input type="text" name=ZNOK01 id="ZNOK01" value="" onChange="chkInputValidity(this);" onKeyDown="dds5250(this);" maxlength="10" size="12" alt="10J">  
<KEYEND>
   から <input type="button" id="GO" value=" GO " class="HAND" onClick="setClickEvent();">
   <input type="button" id="NEW" value="新規レコードの追加" class="HAND" onClick="crtNewRecord();">
</p>
</form>

<hr>
<div class="CLSBTN">
<input type="button" class="HAND" value="閉じる" onClick="clsApplication();">
</div>
<!-- イベントドリブン用 Hidden -->
<input type="hidden" name="ERRMSG" value="$(ERRMSG)">
<input type="hidden" name="REVIMG" value="##########">
<input type="hidden" name="CURSOR" value="##########">
<input type="hidden" name="SFLREVIMG" value="$(SFLREVIMG)">
<input type="hidden" name="SFLCURSOR" value="$(SFLCURSOR)">
</body>
<!-- JavaScript VBScript Lib-->
<script type="text/javascript" src="/AS400-NET.USR/JS/RPG_SP.JS" charset="Shift_JIS"></script>
<script type="text/javascript" src="/AS400-NET.USR/JS/RPG_SP_CLCHK.JS" charset="Shift_JIS"></script>
<script type="text/javascript" src="/AS400-NET.USR/JS/RPG_SP_GUI_EV.JS" charset="Shift_JIS"></script>
<script type="text/vbscript" src="/AS400-NET.USR/JS/CHKFORMAT.VBS" charset="Shift_JIS"></script>
<script type="text/vbscript" src="/AS400-NET.USR/JS/CHKLENGTH.VBS" charset="Shift_JIS"></script>
</html>
					
■ RPG# サンプルソース
     H NOMAIN BNDDIR('ASNET.COM/MAIN') DATEDIT(*YMD/)                       
     F**********  栫距 縁裳 CHINESE SAMPLE
     F*  CHS001      : TYPE: レポート照会    言語 : RPG#   VER 5.1          
     F**********************************************************************
     FCHS001H   CF   E             SPECIAL PGMNAME('ASNET.COM/HTMLDVR')     
     F                                     PLIST(HPARM)                     
     F                                     INFDS(INFDSF)                    
     FZDXXXD    IF   E           K DISK    EXTFILE(ZDXXXD_LIB)              
     F**********************************************************************
                                                                            
     F*---------------------------------------------------------------------
     F* CRTMOD=CRTWEBMOD QTEMP/CHS001 SRCFILE(ASNET.USR/QRPGLESRC) +        
     F*           OPTION(*NOXREF *NOSECLVL *NOEXPDDS *NOSHOWCPY) +          
     F*           DBGVIEW(*SOURCE) AUT(*ALL)                                
     F* CRTPGM=CRTPGM    CGIBIN/CHS001 MODULE(ASNET.COM/MAIN QTEMP/CHS001) +
     F*                  ACTGRP(*NEW) AUT(*ALL)                             
     F* USER=QTMHHTTP                                                       
     F* TYPE=RPG#                                                           
     F* HTML=/AS400-NET.USR/PROJECT/CHS001/DSPHEAD.HTM                      
     F* HTML=/AS400-NET.USR/PROJECT/CHS001/SFLCTL01.HTM                     
     F* LIBL=CGIBIN     CHSFIL     QGPL       QTEMP      ASNET.COM          
     F* CALL=HTTP://218.44.135.18/CGI-BIN/CHS001.PGM                        
     F* TEXT= 栫距 縁裳 CHINESE SAMPLE
     F* SESSION=*NO                                                         
     F* KEEP-ALIVE=*NO                                                      
     F* CCSID=5026                                                          
     F* 作成日 :CRTDATE=2012/10/03  時刻 16:29:28   BY QTMHHTTP             
     F* 変更日 :CHGDATE=2012/10/03  時刻 16:29:28   BY QTMHHTTP             
     F*---------------------------------------------------------------------
                                                                            
      /COPY ASNET.USR/QRPGLESRC,PROTOTYP5#                                  
     D DSPHEAD_GO      PR                                                   
     D SFLCTL01_NXT    PR                                                   
     D READF           PR                                                   
     D HTM_FILE        S             10A   INZ('CHS001H   ')                
     D HTM_LIB         S             10A   INZ('*LIBL     ')                
     D ZDXXXD_LIB      S             21    INZ('CHSFIL/ZDXXXD')             
     D HTM_DIR         S            128A   INZ('/AS400-NET.USR/PROJECT/-    
     D                                     CHS001')                         
     D NOTFOUND        C                   CONST(' レコードが見つからない。 ')
     D MAXGYO          S              4  0 INZ(15)                          
     D SAVKEY          DS                  LIKEREC(ZXXXR     :*KEY)         
                                                                            
     D*( ファイル情報データ構造 )                                           
     D INFDSF          DS                                                   
     D                              512A                                    
     D  HTM_RECORD       *RECORD                                            
     D  FILREC               156    159B 0                                  
     D  DEV                  273    282                                     
     D  SFLRRN               376    377B 0                                  
     D  TOPRRN               378    379B 0                                  
     D*( プログラム状況データ構造 )                                         
     D INFDSP         SDS                                                   
     D                              512A                                    
      /COPY ASNET.USR/QRPGLESRC,INFDSP                                      
      /COPY ASNET.USR/QRPGLESRC,HPARM                                       
     C*-------------------------------------------------------              
     C     SETKEY        KLIST                                              
     C                   KFLD                    ZNOK01                     
     C*-------------------------------------------------------              
                                                                            
     *********************************************************              
     P EVENT           B                   EXPORT                           
     *********************************************************              
     D                 PI                                                   
      /FREE                                                                 
         ON_CLICK('DSPHEAD': 'GO': %PADDR(DSPHEAD_GO));                     
         ON_CLICK('SFLCTL01': 'NXT': %PADDR(SFLCTL01_NXT));                 
      /END-FREE                                                             
     P                 E                                                    
     *********************************************************              
     P BEGIN           B                   EXPORT                           
     *********************************************************              
      * 最初の画面を出力します。                                            
     D                 PI                                                   
     C                   WRITE     DSPHEAD                                  
     P                 E                                                    
                                                                            
     *********************************************************              
     P DSPHEAD_GO      B                   EXPORT                           
     *********************************************************              
      * GO ボタンが押されたときの記述を行います。                           
     D                 PI                                                   
     C                   READ      DSPHEAD                              99  
     C     SETKEY        SETLL     ZDXXXD                                   
     C                   Z-ADD     1             TOPRRN                     
     C                   CALLP     READF                                    
     P                 E                                                    
                                                                            
     *********************************************************              
     P SFLCTL01_NXT    B                   EXPORT                           
     *********************************************************              
      *  次へ  ボタンが押されたときの記述を行います。                       
     D                 PI                                                   
     C                   READ      SFLCTL01                             99  
     C                   Z-ADD     FILREC        SFLRRN                     
     C                   READ      SFREC01                                50
     C     SETKEY        SETGT     ZDXXXD                                   
     C     GYONO         ADD       1             TOPRRN                     
     C                   CALLP     READF                                    
     P                 E                                                    
                                                                            
     *********************************************************              
     P READF           B                   EXPORT                           
     *********************************************************              
      * データ・ベースの読み取り                                            
     D                 PI                                                   
     C                   EVAL      HDR001            = ZNOK01               
     C     1             DO        MAXGYO        SFLRRN                     
     C                   SETOFF                                       50    
     C                   READ      ZDXXXD                                 50
     C   50              CALLP     SETEOF                                   
     C   50              LEAVE                                              
     C                   WRITE     SFREC01                              99  
     C                   END                                                
     C                   WRITE     SFLCTL01                                 
     P                 E                                                    
                                                                            
     *********************************************************              
     P END             B                   EXPORT                           
     *********************************************************              
      * 最後の処理を記述します。                                            
     D                 PI                                                   
     C                   CLOSE     CHS001H                                  
     C                   CLOSE     ZDXXXD                                   
     P                 E                                                    
					
■ 入力サンプルの実行

照会サンプルの初期画面において「新規レコードの追加」ボタンを押すと次のように中国語のデータを
新たに入力することができます。
既存のコードと重複のないコードを指定して更新して、その後にもう一度データを照会して
自分の入力したデータが確かに追加されているかを確認してください。
(最初の「?好1」という10桁の項目(フィールド)がこのデータ・ベースのキーです。)

[註]中国語漢字の入力の方法

■ コピー&ペーストによる中国語の入力

中国語のサイトや翻訳サイトなどのコンテンツより文字をコピーして入力ボックスに貼り付けます。

[参考サイト] 中国語翻訳 - エキサイト翻訳

日本語を簡体字に変換して、変換結果をコピー&ペーストします。

■ ピンイン検索による中国語の入力

中国語のピンイン(中国語発音) によって候補の漢字を選択します。

[参考サイト] 日本語 Windows 7 / Vista / XPで 中国語を入力する方法

Windows XPにおける中国語・韓国語の設定

日本語版Windowsでのピンイン入力の方法が紹介されています。