XML を処理するプロシージャーの記述

独自の処理プロシージャーでは、XML イベントを処理するステートメントをコーディングしてください。

パーサーは、次の表に示すように、検出するイベントごとに情報をいくつかの特殊レジスターに入れて処理プロシージャーに渡します。 これらのレジスターを使用して、データ構造を取り込み、ま た処理を制御します。

表 15. XML パーサーの使用する特殊レジスター
特殊レジスター 内容 暗黙的な定義および使用
XML-EVENT1 XML イベントの名前 PICTURE X(30) USAGE DISPLAY
VALUE SPACE
XML-CODE 各 XML イベントに対し、例外コードまたは 0 PICTURE S9(9) USAGE BINARY
VALUE ZERO
XML-TEXT1 XML PARSE ID で英数字データ項目を指定した場合、 パーサーが見つけたイベントに対応する XML 文書のテキスト。 可変長の英数字データ項目。サイズ制限 16,000,000 バイト
XML-NTEXT1 XML PARSE ID で国別データ項目を指定した場合、 パーサーが見つけたイベントに対応する XML 文書のテキスト。 可変長の国別データ項目。サイズ制限 16,000,000 バイト
  1. この特殊レジスターを、受け取りデータ項目として使用できません。

ネストされたプログラムで使用する場合、 これらの特殊レジスターは、最外部のプログラムで暗黙のうちに GLOBAL として定義されます。

XML-CODE の内容の理解

パーサーが XML PARSE ステートメントに制御を戻すとき、 XML-CODE はパーサーまたは処理プロシージャーが設定した最新の値を含みます。

EXCEPTION イベントを除くすべてのイベントでは、 特殊レジスター XML-CODE の値は 0 です。 EXCEPTION 以外のイベントで、 XML パーサーに制御を戻す前に特殊レジスター XML-CODE を -1 に設定すると、戻された XML-CODE の -1 の値が示すユーザー開始の例外により、処理は停止されます。 イベントから戻る前に XML-CODE を 非ゼロ値に変更することによる結果は、定義されていません。

EXCEPTION イベントでは、 特殊レジスター XML-CODE は例外コードを含みます。

次の図は、パーサーと処理プロシージャーの間の制御のフローと、 両者の間の情報の受け渡しに XML-CODE がどのように使用されているかを示しています。 画像説 明の開始。 他ページへのフローチャート接続記号。画像説明終了。 のような他ページへの接続記号は、 この章の複数の図表を接続します。 特に、次の図中の 画像記述開始。他ページへの接続記号 E。画像記述終了。 は、図形『XML 例外の制御フロー』に接続し、 また 画像記述開始。 他ページへの接続記号 P。画像記述終了。 は、『XML CCSID 例外のフロー制御』から接続します。

XML-CODE の使用方法を 示す、XML パーサーとプログラムの間の制御フロー

画像記述開始。XML パーサーとプログラムの間の 制御フローのフローチャートおよび周囲のテキストによる XML-CODE の使用方法の説明 画像記述終了。

XML-TEXT および XML-NTEXT の使用

特殊レジスター XML-TEXT および XML-NTEXT は、 相互に排他的です。 ユーザーの指定する XML ID のタイプにより、どちらの特殊レジスター が設定されるかが決まります。 ただし、ATTRIBUTE-NATIONAL-CHARACTER お よび CONTENT-NATIONAL-CHARACTER イベントは例外です。 これらのイベントでは、XML PARSE の ID に指定したデータ項目に関わらず XML-NTEXT が設定されます。

パーサーが XML-TEXT を設定するときは、 XML-NTEXT は未定義 (長さ 0) です。 パーサーが XML-NTEXT を設定するときは、 XML-TEXT は未定義 (長さ 0) です。

XML-NTEXT が含む国別文字の数を判別するには、 LENGTH 関数を使用します。 LENGTH OF XML-NTEXT は、XML-NTEXT で使用されている文字数ではなくバイト数を含みます。

XML テキストの COBOL データ項目への変換

XML データは固定長でなく、また形式も固定されていないため、 XML データを COBOL データ項目に移すには特殊な手法を使用する必要があります。

英数字項目の場合は、XML データが COBOL 項目に左寄せ (デフォルト) で入るか、右寄せで入るかを決定します。 右寄せで入る場合、COBOL 項目の宣言で JUSTIFIED RIGHT 文節を指定します。

数値の XML 値に関しては、特別な考慮が必要です。 特に、「$1,234.00」や「$1234」のような「修飾」された金額値の場合がそうです。 これらは、XML では同じ意味ですが、COBOL の送り側フィールドとしての宣言は全く違います。 次の手法を使用してください。

処理プロシージャーの制約事項

ユーザーの処理プロシージャーは、直接 XML PARSE ステートメントを実行してはなりません。 ただし、処理プロシージャーが CALL ステートメントを使用して 最外部のプログラムに制御を渡す場合、 そのターゲットのメソッドまたはプログラムは、同じ XML PARSE ステートメントや 別の XML PARSE ステートメントを実行することができます。 また、複数のスレッドで実行しているプログラムから、 同じ XML ステートメントまたは別の XML ステートメントを同時に実行することができます。

処理プロシージャーの終了

コンパイラーは、処理プロシージャーの最後のステートメントの後に 、戻るためのメカニズムを挿入します。 処理プロシージャー中に STOP RUN ステートメントをコーディングすることで、 実行単位を強制終了させることができます。 ただし、GOBACK または EXIT PROGRAM ステートメントは、 パーサーに制御を戻しません。 処理プロシージャー中にいずれのステートメントを使用しても、 重大エラーが発生します。

例: XML 構文解析

関連リファレンス
継続可能な XML 例外
継続不可能な XML 例外
『XML-CODE』(「ILE COBOL 言語解説書」)
『XML-EVENT』(「ILE COBOL 言語解説書」)
『XML-NTEXT』(「ILE COBOL 言語解説書」)
『XML-TEXT』(「ILE COBOL 言語解説書」)

例: XML 構文解析

この例は、XML PARSE ステートメントおよび処理プロシージャーの基本的な編成を示します。 ここでは、XML 文書は COBOL データ項目に入っています。 構文解析のフローを追うことができるように、XML 文書はソースで挙げられています。 プログラムの出力は下に挙げられています。 文書とプログラムの出力を比較し、 パーサーと処理プロシージャーの相互作用を追い、イベントと文書断片 を突き合わせてください。

例: データ項目からの XML 構文解析

 Process APOST
 Identification division.
   Program-id. xmlsampl1.

 Data division.
  Working-storage section.
******************************************************************
* XML document, encoded as initial values of data items.         *
******************************************************************
   1 xml-document.
    2 pic x(39) value '<?xml version="1.0" encoding="ibm-37"'.
    2 pic x(19) value ' standalone="yes"?>'.
    2 pic x(39) value '<!--This document is just an example-->'.
    2 pic x(10) value '<sandwich>'.
    2 pic x(35) value '  <bread type="baker&apos;s best"/>'.
    2 pic x(41) value '  <?spread please use real mayonnaise  ?>'.
    2 pic x(31) value '  <meat>Ham &amp; turkey</meat>'.
    2 pic x(40) value '  <filling>Cheese, lettuce, tomato, etc.'.
    2 pic x(10) value '</filling>'.
    2 pic x(35) value '  <![CDATA[We should add a <relish>'.
    2 pic x(22) value ' element in future!]]>'.
    2 pic x(31) value '  <listprice>$4.99 </listprice>'.
    2 pic x(27) value '  <discount>0.10</discount>'.
    2 pic x(11) value '</sandwich>'.
   1 xml-document-length computational pic 999.

******************************************************************
* Sample data definitions for processing numeric XML content.    *
******************************************************************
   1 current-element pic x(30).
   1 list-price computational pic 9v99 value 0.
   1 discount computational pic 9v99 value 0.
   1 display-price pic $$9.99.

 Procedure division.
  mainline section.

     XML PARSE xml-document PROCESSING PROCEDURE xml-handler
       ON EXCEPTION
         display 'XML document error ' XML-CODE
       NOT ON EXCEPTION
         display 'XML document successfully parsed'
     END-XML

******************************************************************
*    Process the transformed content and calculate promo price.  *
******************************************************************
     display ' '
     display '-----+++++***** Using information from XML '
         '*****+++++-----'
     display ' '
     move list-price to display-price
     display '  Sandwich list price: ' display-price
     compute display-price = list-price * (1 - discount)
     display '  Promotional price:   ' display-price
     display '  Get one today!'

     goback.

  xml-handler section.
     evaluate XML-EVENT
* ==> Order XML events most frequent first
       when 'START-OF-ELEMENT'
         display 'Start element tag: <' XML-TEXT '>'
         move XML-TEXT to current-element
       when 'CONTENT-CHARACTERS'
         display 'Content characters: <' XML-TEXT '>'
* ==> Transform XML content to operational COBOL data item...
         evaluate current-element
           when 'listprice'
* ==> Using function NUMVAL-C...
             compute list-price = function numval-c(XML-TEXT)
           when 'discount'
             compute discount = function numval-c(XML-TEXT)
         end-evaluate
       when 'END-OF-ELEMENT'
         display 'End element tag: <' XML-TEXT '>'
         move spaces to current-element
       when 'START-OF-DOCUMENT'
         compute xml-document-length = function length(XML-TEXT)
         display 'Start of document: length=' xml-document-length
             ' characters.'
       when 'END-OF-DOCUMENT'
         display 'End of document.'
       when 'VERSION-INFORMATION'
         display 'Version: <' XML-TEXT '>'
       when 'ENCODING-DECLARATION'
         display 'Encoding: <' XML-TEXT '>'
       when 'STANDALONE-DECLARATION'
         display 'Standalone: <' XML-TEXT '>'
       when 'ATTRIBUTE-NAME'
         display 'Attribute name: <' XML-TEXT '>'
       when 'ATTRIBUTE-CHARACTERS'
         display 'Attribute value characters: <' XML-TEXT '>'
       when 'ATTRIBUTE-CHARACTER'
         display 'Attribute value character: <' XML-TEXT '>'
       when 'START-OF-CDATA-SECTION'
         display 'Start of CData: <' XML-TEXT '>'
       when 'END-OF-CDATA-SECTION'
         display 'End of CData: <' XML-TEXT '>'
       when 'CONTENT-CHARACTER'
         display 'Content character: <' XML-TEXT '>'
       when 'PROCESSING-INSTRUCTION-TARGET'
         display 'PI target: <' XML-TEXT '>'
       when 'PROCESSING-INSTRUCTION-DATA'
         display 'PI data: <' XML-TEXT '>'
       when 'COMMENT'
         display 'Comment: <' XML-TEXT '>'
       when 'EXCEPTION'
         compute xml-document-length = function length (XML-TEXT)
         display 'Exception ' XML-CODE ' at offset '
             xml-document-length '.'
       when other
         display 'Unexpected XML event: ' XML-EVENT '.'
     end-evaluate
     .
 End program xmlsampl1.
構文解析例の出力

次の出力から、構文解析のどのイベントが、文書のどの断片から起こ るかを知ることができます。

Start of document: length=390 characters.
Version: <1.0>
Encoding: <ibm-37>
Standalone: <yes>
Comment: <This document is just an example>
Start element tag: <sandwich>
Content characters: <  >
Start element tag: <bread>
Attribute name: <type>
Attribute value characters: <baker>
Attribute value character: <'>
Attribute value characters: <s best>
End element tag: <bread>
Content characters: <  >
PI target: <spread>
PI data: <please use real mayonnaise  >
Content characters: <  >
Start element tag: <meat>
Content characters: <Ham >
Content character: <&>
Content characters: < turkey>
End element tag: <meat>
Content characters: <  >
Start element tag: <filling>
Content characters: <Cheese, lettuce, tomato, etc.>
End element tag: <filling>
Content characters: <  >
Start of CData: <<![CDATA[>
Content characters: <We should add a <relish> element in future!>
End of CData: <]]>>
Content characters: <  >
Start element tag: <listprice>
Content characters: <$4.99 >
End element tag: <listprice>
Content characters: <  >
Start element tag: <discount>
Content characters: <0.10>
End element tag: <discount>
End element tag: <sandwich>
End of document.
XML document successfully parsed

-----+++++***** Using information from XML *****+++++-----

  Sandwich list price:  $4.99
  Promotional price:    $4.49
  Get one today!

例: IFS ファイルからの XML 構文解析

この例は、IFS ファイル中にある XML 文書を構文解析する XML PARSE ステートメントを示します。 プログラムの出力は、前の例と同じです。 IFS ファイルには、有効な CCSID が必要です。 IFS ファイルの各行の終わりには CR (復帰) のみが必要であり、LF (改行) があってはなりません。

 Process APOST
 Identification division.
   Program-id. xmlsampl2.

 Data division.
  Working-storage section.
******************************************************************
* XML document, encoded as initial values of data items.         *
******************************************************************
   1 xml-id pic x(27) value '/home/user1/xmlsampldoc.xml'.
   1 xml-document-length computational pic 999.

******************************************************************
* Sample data definitions for processing numeric XML content.    *
******************************************************************
   1 current-element pic x(30).
   1 list-price computational pic 9v99 value 0.
   1 discount computational pic 9v99 value 0.
   1 display-price pic $$9.99.

 Procedure division.
  mainline section.

     XML PARSE FILE-STREAM xml-id PROCESSING PROCEDURE xml-handler
       ON EXCEPTION
         display 'XML document error ' XML-CODE
       NOT ON EXCEPTION
         display 'XML document successfully parsed'
     END-XML

******************************************************************
*    Process the transformed content and calculate promo price.  *
******************************************************************
     display ' '
     display '-----+++++***** Using information from XML '
         '*****+++++-----'
     display ' '
     move list-price to display-price
     display '  Sandwich list price: ' display-price
     compute display-price = list-price * (1 - discount)
     display '  Promotional price:   ' display-price
     display '  Get one today!'

     goback.

  xml-handler section.
     evaluate XML-EVENT
* ==> Order XML events most frequent first
       when 'START-OF-ELEMENT'
         display 'Start element tag: <' XML-TEXT '>'
         move XML-TEXT to current-element
       when 'CONTENT-CHARACTERS'
         display 'Content characters: <' XML-TEXT '>'
* ==> Transform XML content to operational COBOL data item...
         evaluate current-element
           when 'listprice'
* ==> Using function NUMVAL-C...
             compute list-price = function numval-c(XML-TEXT)
           when 'discount'
             compute discount = function numval-c(XML-TEXT)
         end-evaluate
       when 'END-OF-ELEMENT'
         display 'End element tag: <' XML-TEXT '>'
         move spaces to current-element
       when 'START-OF-DOCUMENT'
         compute xml-document-length = function length(XML-TEXT)
         display 'Start of document: length=' xml-document-length
             ' characters.'
       when 'END-OF-DOCUMENT'
         display 'End of document.'
       when 'VERSION-INFORMATION'
         display 'Version: <' XML-TEXT '>'
       when 'ENCODING-DECLARATION'
         display 'Encoding: <' XML-TEXT '>'
       when 'STANDALONE-DECLARATION'
         display 'Standalone: <' XML-TEXT '>'
       when 'ATTRIBUTE-NAME'
         display 'Attribute name: <' XML-TEXT '>'
       when 'ATTRIBUTE-CHARACTERS'
         display 'Attribute value characters: <' XML-TEXT '>'
       when 'ATTRIBUTE-CHARACTER'
         display 'Attribute value character: <' XML-TEXT '>'
       when 'START-OF-CDATA-SECTION'
         display 'Start of CData: <' XML-TEXT '>'
       when 'END-OF-CDATA-SECTION'
         display 'End of CData: <' XML-TEXT '>'
       when 'CONTENT-CHARACTER'
         display 'Content character: <' XML-TEXT '>'
       when 'PROCESSING-INSTRUCTION-TARGET'
         display 'PI target: <' XML-TEXT '>'
       when 'PROCESSING-INSTRUCTION-DATA'
         display 'PI data: <' XML-TEXT '>'
       when 'COMMENT'
         display 'Comment: <' XML-TEXT '>'
       when 'EXCEPTION'
         compute xml-document-length = function length (XML-TEXT)
         display 'Exception ' XML-CODE ' at offset '
             xml-document-length '.'
       when other
         display 'Unexpected XML event: ' XML-EVENT '.'
     end-evaluate
     .
 End program xmlsampl2.

以下が /home/user1/xmlsampldoc.xml にある、この例の IFS ファイルです。

<?xml version="1.0" encoding="ibm-37"
  standalone="yes"?>
<!--This document is just an example-->
<sandwich>
 <bread type="baker&apos;s best"/>
 <?spread please use real mayonnaise  ?>
 <meat>Ham &amp; turkey</meat>
 <filling>Cheese, lettuce, tomato, etc.
</filling>
 <![CDATA[We should add a <relish> element in future!]]>
 <listprice>$4.99 </listprice>
 <discount>0.10</discount>
</sandwich>