データベース

36. RPG でXMLを使うには (2)

先の説明でXMLとは何かは理解して頂けたと思う。
そしてRPGではXMLをデータ構造(DS)にマッピングする演算命令として

XML-INTO という命令があることも紹介した。

そして現在、IBM関連のサイトでXML-INTOのサンプル・ソースが
紹介されているがそれらのすべては実は動作しない
これはIBMのRPG解説書やRPGプログラマーの手引きで紹介されているものも
すべて含めて動作しないものである。
正確に言えば日本語環境ではi5/OS Ver7.4であっても動作しない。
それはXML-INTO命令が日本語環境を考慮されていないことに起因している。
日本のサイトで公開しているサンプル・ソースも日本語環境では
全く動作しない。
そこで

CHGJOB CCSID(37)
XML-INTO ….

とするとXML-INTOは動作するがこれではXMLに漢字データが
含まれているとエラーになってこれも正常に動作することができない。

そこで正常にXML-INTOを日本語環境で動作させるようにした
国内で第一号のソースが次のサンプル・ソースである。

[日本語環境で動作する初めてのXML-INTO RPGサンプル: TESTXML ]

ソースはこちらから

0001.00 H DFTNAME(TESTXML) DATEDIT(*YMD/) BNDDIR('QC2LE')                        
0002.00 H CCSID(*GRAPH:*SRC)                                                     
0003.00 F********** XML_INTO のテスト *****************************************  
0004.00 F*                                                                       
0005.00 F**********************************************************************  
0006.00                                                                          
0007.00  * CRTBNDRPG  OBJ(OBJLIB/TESTXML)  SRCFILE(MYSRCLIB/QRPGLESRC)           
0008.00  * DFTACTRP(*NO) ACTGRP(*NEW) DBGVIEW(*SOURCE) AUT(*ALL)                 
0009.00                                                                          
0010.00  *-------------------------------------------------------------------*   
0011.00  *  2021/11/27 : 作成                                                    
0012.00  *-------------------------------------------------------------------*   
0013.00  *( 作業変数 )                                                           
0014.00 D XML             S            512C   CCSID(1200)                        
0015.00                                                                          
0016.00 D RECORD          DS                  QUALIFIED                          
0017.00 D   SHCODE                1     10A                                      
0018.00 D   SHNAME               11     34A                                      
0019.00 D   SHTANK               35     41S 0                                    
0020.00 D   SHSCOD               42     45A                                      
0021.00                                                                          
0022.00  /FREE                                                                   
0023.00    XML = %UCS2('+                                                
0024.00             NV-CF1+                                
0025.00              Cカセット編集ビデオ +                
0026.00             58000+                                 
0027.00             0002+                                  
0028.00           ');                                              
0029.00    XML-INTO RECORD %XML(XML:'ccsid=ucs2 case=any');                 
0030.00  /END-FREE                                                          
0031.00 C                   SETON                                        LR 
0032.00 C                   RETURN   


                                        

[コンパイル]

CRTBNDRPG PGM(OBJLIB/TESTXML) SRCFILE(MYSRCLIB/QRPGLESRC) DFTACTGRP(*NO)
ACTGRP(*NEW) DBGVIEW(*SOURCE) AUT(*ALL)

[解説]

まず Unicode変数(USC-2)として XML を

0014.00 D XML             S            512C   CCSID(1200)

のように定義する。変数のタイプは A ではなく C であることに注意。CCSIDは 1200 (=UTF16)である。
次にXMLと同じデータ構造 : RECORD を

0016.00 D RECORD          DS                  QUALIFIED                          
0017.00 D   SHCODE                1     10A                                      
0018.00 D   SHNAME               11     34A                                      
0019.00 D   SHTANK               35     41S 0                                    
0020.00 D   SHSCOD               42     45A 

として定義する。データ構造の名前 RECORD とXMLの名前 RECORD は同じにしなければならない。
次にXMLの内容を

0022.00  /FREE                                                                   
0023.00    XML = %UCS2(<RECORD>+                                                
0024.00             <SHCODE>NV-CF1<<SHCODE>+                                
0025.00             <SHNAME> Cカセット編集ビデオ </SHNAME>+                
0026.00             <SHTANK>58000</SHTANK>+                                 
0027.00             <SHSCOD>0002</SHSCOD>+                                  
0028.00           </RECORD>'); 

として代入するが組込み関数 %UCS2 によって + … の値はUTF-16に変換されて
XMLの中に保管される。
最後に XML-INTO命令を使って

0029.00    XML-INTO RECORD %XML(XML:'ccsid=ucs2 case=any');

のようにしてXMLをデータ構造(DS): RECORD に変換するというわけである。
このとき XML-INTO のオプションとして

ccsid=usc2 の指定によってXMLの値はUTF-16であることを宣言しておくと

XMLのUTF-16からEBCDICのデータ構造へと変換されるのである。
XML-INTO では CCSID 5026, 5035および 1399からの変換はサポートされていない。
唯一、日本語と互換性があるのはUTF-16だけである。
それゆえUTF-16からの変換が指示されていないIBM解説書やIBM特約店がやIBM SEが
紹介しているXML-INTOのサンプル・ソースは全く動作できないのである。
これも実際に実験してみればすぐにわかることであるが
彼等は全くテストもせずにサンプル・ソースとして公開しているのだろう。

もうひとつ case=any とオプション指定しているがXML-INTO のXMLの省略値は
case=lower つまり英子文字を標準としているので
英大文字を使う場合は case=upper または case=any の指定が必要である。

この注意点はどのサイトにも紹介されていない。
つまり彼らは実際に動作させたことがないのである。

実際にデータ構造に展開されているかどうかは
STRDBG でデバッグ・モードで動作させて31行目でデータ構造RECORDを表示させてみれば
確認することができる。

[STRDBG で EVAL RECORD ]

                                   評価式     
                                              
前のデバッグ式                                
                                              
> EVAL record                                 
  RECORD.SHCODE = 'NV-CF1    '                
  RECORD.SHNAME = ' Cカセット編集ビデオ   '  
  RECORD.SHTANK = 0058000.                    
  RECORD.SHSCOD = '0002'                      
                                              

これが日本語環境で初めて動作したXML-INTOである。
今回は簡単に文字列からのパースを行ったが次回は実際にIFSからのファイルのXMLを
パースする方法を紹介する。