XML-INTO または XML-SAX ステートメントを使用して RPG プログラムから XML 文書を処理することができます。このステートメントは、高速 XML パーサーへの RPG 言語インターフェースです。RPG で現在使用されているパーサーは、多数の適格性エラーに対して XML 文書を検査しますが、非有効化パーサーです。 XML パーサーについて詳しくは、「ILE COBOL プログラマーの手引き」の付録『XML 参照資料』にある『XML 適合性』節を参照してください。
XML 文書は、文字でも UCS-2 RPG 変数でもよく、または統合ファイル・システムのファイル内にあってもかまいません。
パーサーは、SAX パーサーです。SAX パーサーは、XML 文書を文字単位で読み込んで動作します。要素名、または属性値などの XML 文書の断片を見つけたときはいつでも、パーサーの発呼者が提供する処理手順に答えて、見つけた XML の断片に関する情報を渡します。例えば、パーサーが XML 要素名を見つけた場合、パーサーは、"イベント" が "start element" イベントであることを示す処理手順を呼び出し、エレメントの名前を渡します。
処理手順は、情報を処理し、別のイベントで処理手順を呼び出すのに十分な情報を持つまで XML 文書を読み込み続けるパーサーに戻ります。このプロセスは、XML 文書全体が構文解析されるか、処理手順が構文解析を終了する必要があることを示すまで、繰り返されます。
例えば、以下の XML 文書について考えてみてください。
<email type="text"> <sendto>JohnDoe@there</sendto> </email>
以下は、パーサーが読み込むテキストの断片、パーサーが生成するイベント、および各イベントに関連するデータです。注: 用語 "whitespace" は、行の終わりの文字、タブ文字およびブランクを指します。
構文解析されたテキスト | イベント | イベント・データ |
---|---|---|
start document | ||
start element | "email" | |
type= | attribute name | "type" |
"text" | attribute value | "text" |
>whitespace | element content | the whitespace |
<sendto> | start element | "sendto" |
JohnDoe@there | element content | "JohnDoe@there" |
</sendto> | end element | "sendto" |
whitespace | element content | the whitespace |
</email> | end element | "email" |
end document |
XML-SAX および XML-INTO 命令コードでは、XML パーサーを使用することができます。
例えば、XML 文書が type という名前の XML 属性を含むことが分かっていて、この属性の値を知りたい場合は、処理手順は "attribute name" イベントが "type" の値を持つまで待つことができます。 次回呼び出されるハンドラーは、必要なデータ (上記の例では "text") を持つ "attribute value" イベントである必要があります。
例えば、XML 文書が常に上記の文書の形式を持っていることが分かっている場合は、 名前 "email"、およびサブフィールド "type" および "sendto" を持つ RPG データ構造を定義することができます。次に、XML-INTO 命令を使用して 、XML 文書をデータ構造に直接読み込むことができます。命令が完了したとき、 "type" サブフィールドは値 "text" を持ち、"sendto" サブフィールドは 値 "JohnDoe@there" を持ちます。
XML データは、常にテキスト形式でパーサーによって戻されます。データが数値データ、または日付データなどの他のデータ・タイプを表すことが分かっている場合、XML-SAX 処理手順は、%INT または %DATE などの変換関数を使用してデータを変換する必要があります。
XML-INTO 命令は、文字データをレシーバーとして指定してフィールドまたはサブフィールドのタイプに自動的に変換します。
XML-SAX および XML-INTO 命令の両方で、命令を制御する一連のオプションを指定できます。 このオプションは、以下の形式の 1 つの文字式で指定されます。
'opt1=val1 opt2=val2'
各命令は、独自の有効なオプションのセットを持っています。両方の命令コードに共通なオプションは以下のとおりです。
XML パーサーが構文解析時に XML 文書でエラーを検出した場合、 メッセージ RNX0351 が出力されます。メッセージから、エラーが発見された文書内のオフセットと同様に、エラーに関連する特定のエラー・コードを得ることができます。
以下の表は、各パーサー・エラー・コードの意味を示します。
XML パーサー・エラー・コード | 説明 |
---|---|
1 | パーサーは、要素コンテントの外側の空白文字をスキャン中に無効な文字を見つけました。 |
2 | パーサーは、要素コンテントの外側に、処理命令、要素、コメント、または文書タイプ宣言の無効な開始を見つけました。 |
3 | パーサーは、重複属性名を見つけました。 |
4 | パーサーは、属性値にマークアップ文字 '<' を見つけました。 |
5 | 要素の開始および終了タグ名が一致しませんでした。 |
6 | パーサーは、要素コンテントに無効文字を見つけました。 |
7 | パーサーは、要素コンテントに、要素、コメント、処理命令、または CDATA セクションの無効な開始を見つけました。 |
8 | パーサーは、要素コンテントに、マッチする開始文字シーケンス '<![CDATA[' のない CDATA 終了文字シーケンス ']]>' を見つけました。 |
9 | パーサーは、コメントに無効文字を見つけました。 |
10 | パーサーは、コメントに、'>' が続かない文字シーケンス '--' (2 つのハイフン) を見つけました。 |
11 | パーサーは、処理命令データ・セグメントに無効文字を見つけました。 |
12 | 処理命令ターゲット名は、小文字、大文字、または大/小文字混合の 'xml' でした。 |
13 | パーサーは、16 進文字参照に無効桁を見つけました (形式 �、例えば ັ)。 |
14 | パーサーは、小数点文字参照に無効桁を見つけました (形式 &#dddd;)。 |
15 | 文字参照は、合法な XML 文字を参照しませんでした。 |
16 | パーサーは、エンティティー参照名に無効文字を見つけました。 |
17 | パーサーは、属性値に無効文字を見つけました。 |
18 | パーサーは、起こりうる文書タイプ宣言の無効開始を見つけました。 |
19 | パーサーは、2 番目の文書タイプ宣言を見つけました。 |
20 | 要素名は正しく指定されませんでした。最初の文字が文字 '_' または ':' でなかったか、または、パーサーが要素名内または要素名に続いて無効文字を見つけました。 |
21 | 属性は正しく指定されませんでした。属性名の最初の文字が文字 '_' または ':' でなかったか、または '=' 以外の文字が属性名に続いて見つかったか、値の区切り文字のいずれかが不正確だったか、無効文字がその名前内またはその名前に続いて見つかりました。 |
22 | 空の要素タグが '/' が続く '>' で終了しませんでした。 |
23 | 要素終了タグが正しく指定されませんでした。最初の文字が文字 '_' または ':' でなかったか、またはタグが '>' で終了しませんでした。 |
24 | パーサーは、要素コンテントにコメントまたは CDATA セクションの無効な開始を見つけました。 |
25 | 処理命令ターゲット名は、正しく指定されませんでした。処理命令ターゲット名の最初の文字が文字 '_' または ':' でなかったか、または、パーサーが処理命令ターゲット名内またはそれに続いて無効文字を見つけました。 |
26 | 処理命令が終了文字シーケンス '?>' で終了しませんでした。 |
27 | パーサーは、文字参照またはエンティティー参照で、'&' に続いて無効文字を見つけました。 |
28 | XML 宣言にバージョン情報が存在しませんでした。 |
29 | XML 宣言で 'version' が正しく指定されませんでした。'version' の後に '=' が続かなかったか、値が欠落していたか、不適切に区切り文字で区切られていたか、値が不正な文字を指定したか、開始および終了区切り文字が一致しなかったか、パーサーが XML 宣言でバージョン情報値終了区切り文字に続いて無効文字を見つけました。 |
30 | パーサーは、XML 宣言にオプションのエンコード宣言の代わりに無効属性を見つけました。 |
31 | XML 宣言のエンコード宣言値が欠落しているか、不正でした。 値が小文字または大文字の A から Z で始まらなかったか、 'encoding' の後に '=' が続かなかったか、値が欠落していたか、不適切に区切り文字で区切られていたか、不正な文字を指定したか、開始および終了区切り文字が一致しなかったか、パーサーが終了区切り文字に続いて無効文字を見つけました。 |
32 | パーサーは、XML 宣言にオプションのスタンドアロン宣言の代わりに無効属性を見つけました。 |
33 | XML 宣言で 'standalone' 属性が正しく指定されませんでした。'standalone' の後に '=' が続かなかったか、値が欠落していたか、または不適切に区切り文字で区切られていたか、値が 'yes' でも 'no' でもなかったか、値が不正な文字を指定したか、開始および終了区切り文字が一致しなかったか、パーサーが終了区切り文字に続いて無効文字を見つけました。 |
34 | XML 宣言は、適切な文字シーケンス '?>' で終了しなかったか、無効属性を含んでいました。 |
35 | パーサーは、ルート要素の終了の後に文書タイプ宣言の開始を見つけました。 |
36 | パーサーは、ルート要素の終了の後に要素の開始を見つけました。 |
300 | パーサーは、文書が完了する前に文書の終わりに到達しました。 |
301 | XML-INTO または XML-SAX の %HANDLER プロシージャーが非ゼロ値を戻し、XML 構文解析が終了しました。 |
302 | パーサーが要求された CCSID 値をサポートしないか、XML 文書の最初の文字が '<' ではありませんでした。 |
303 | 文書は、パーサーが処理するには大き過ぎました。パーサーは不完全な文書を構文解析しようとしましたが、構文解析の完了には文書の終わりのデータが必要でした。 |
500-999 | 外部パーサーでの内部エラーです。サービス技術員にエラーを報告してください。 |
10001-19999 | パーサーでの内部エラーです。サービス技術員にエラーを報告してください。 |
* Parameters: * 1. path : a pointer to a null-terminated string containing * the path to the file to be written * 2. dataPtr : a pointer to the data to be written * 3. dataLen : the length of the data in bytes * 4. dataCcsid : the CCSID of the data * 5. fileCcsid : the desired CCSID of the file * Sample RPG coding: * ifsWrite ('/home/mydir/temp.xml' : xmlPtr : xmlLen : 37 : 37); * xml-into ds %xml('/home/mydir/temp.xml' : 'doc=file'); * To delete the file, use the system command * rmvlnk '/home/mydir/temp.xml'
* Note: This module requires BNDDIR(QC2LE) P ifsWrite B EXPORT D ifsWrite PI D path * VALUE OPTIONS(*STRING) D dataPtr * VALUE D dataLen 10I 0 VALUE D dataCcsid 10I 0 VALUE D fileCcsid 10I 0 VALUE D O_CREAT C x'00000008' D O_TRUNC C x'00000040' D O_WRONLY C x'00000002' D O_RDWR C x'00000004' D O_CCSID C x'00000020' D O_TEXT_CREAT C x'02000000' D O_TEXTDATA C x'01000000' D O_SHARE_NONE C x'00080000' D S_IRUSR C x'0100' D S_IROTH C x'0004' D S_IRGRP C x'0020' D S_IWUSR C x'0080' D S_IWOTH C x'0002'
D ssize_t S 10I 0 D size_t S 10U 0 D open PR 10I 0 EXTPROC('open') D path * VALUE OPTIONS(*STRING) D flag 10I 0 VALUE D mode 10I 0 VALUE D fileCcsid 10I 0 VALUE options(*nopass) D dataCcsid 10I 0 VALUE options(*nopass) D writeFile PR LIKE(ssize_t) D EXTPROC('write') D handle 10I 0 VALUE D data * VALUE D len VALUE LIKE(size_t) D closeFile PR 10I 0 EXTPROC('close') D handle 10I 0 VALUE D oflag S 10I 0 D omode S 10I 0 D handle S 10I 0 D rc S 10I 0 D sysErrno PR * EXTPROC('__errno') D errno S 10I 0 BASED(pErrno) /FREE pErrno = sysErrno(); oflag = 0 + O_WRONLY + O_CREAT + O_TEXT_CREAT + O_TRUNC + O_CCSID + O_TEXTDATA + O_SHARE_NONE; omode = 0 + S_IRUSR + S_IWUSR + S_IRGRP + S_IROTH; handle = open(path : oflag : omode : fileCcsid : dataCcsid);
// insert error handling if handle is less than zero rc = writeFile (handle : dataPtr : dataLen); // insert error handling if rc is not zero rc = closeFile (handle); // insert error handling if rc is not zero /END-FREE P ifswrite E
(C) Copyright IBM Corporation 1992, 2006. All Rights Reserved.