次の例は、PLISAXD 組み込みサブルーチンの使用方法を示しており、前述の XML 文書と XML スキーマの例を使用しています。
この例には、同じ stock.osr スキーマに対する 8 個の XML ファイルの妥当性検査が含まれています。次の出力で、スキーマに対する妥当性検査が失敗した saxdtest プログラム内の XML 文書を確認できます。
PLISAXD 組み込みサブルーチンでは、XML スキーマ・ファイルをバッファーに読み取る必要があります。 次の例の OSR ファイルは PDS 内にあります。 OSR バッファーの初期サイズは 4096 に設定されています。 それより大きいサイズの OSR ファイルがある場合は、それに応じて OSR バッファーの初期サイズを大きくすることができます。
インバウンド・スキーマ・ファイルが HFS ファイル内にある場合は、次のコードを使用して、OSR ファイルをバッファーへ読み取ることができます。
dcl osrin file input stream environment(u); dcl fileddint builtin; dcl fileread builtin; /* Read the HFS OSR file into buffer*/ open file(osrin); osr_length = fileddint( osrin, 'filesize'); osr_ptr = allocate(osr_length); rc = fileread(osrin,osr_ptr,osr_length);
PDS 内の OSR を使用してプログラムを実行するには、JCL で次の DD ステートメントを指定できます。
//OSRIN DD DSN=HLQ.XML.OSR(STOCK),DISP=SHR
関連付けられた ddname OSRIN が HFS ファイルである場合は、代わりに次の JCL ステートメントを使用します。
//OSRIN DD PATH="/u/HLQ/xml/stock.osr"
saxdtest: package exports(saxdtest);
/************************************************************/
/* saxdtest: Test PL/I XML validation support */
/* expected output: */
/* */
/* SAXDTEST: PL/I XML Validation sample */
/* SAXDTEST: Document Successfully parsed */
/* SAXDTEST: Document Successfully parsed */
/* Invalid: missing attribute itemNumber. */
/* exception return_code =00000018, reason_code =8613 */
/* Invalid: unexpected attribute warehouse. */
/* exception return_code =00000018, reason_code =8612 */
/* Invalid: illegal attribute value 123-Ab. */
/* exception return_code =00000018, reason_code =8809 */
/* Invalid: missing element quantityOnHand. */
/* exception return_code =00000018, reason_code =8611 */
/* Invalid: unexpected element comment. */
/* exception return_code =00000018, reason_code =8607 */
/* Invalid: out-of-range element value 100 */
/* exception return_code =00000018, reason_code =8803 */
/* */
/************************************************************/
define alias event
limited entry( pointer, pointer, fixed bin(31) )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
define alias event_with_flag
limited entry( pointer, pointer, fixed bin(31),
bit(8) aligned )
returns( byvalue fixed bin(31) )
options( nodescriptor byvalue linkage(optlink) );
define alias event_with_namespace
limited entry( pointer, pointer, fixed bin(31),
pointer, fixed bin(31),
pointer, fixed bin(31) )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
define alias event_without_data
limited entry( pointer )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
define alias event_pi
limited entry( pointer, pointer, fixed bin(31),
pointer, fixed bin(31) )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
define alias event_namespace_dcl
limited entry( pointer, pointer, fixed bin(31),
pointer, fixed bin(31) )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
define alias event_exception
limited entry( pointer, fixed bin(31),
fixed bin(31),
fixed bin(31) )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
define alias event_end_of_input
limited entry( pointer,
pointer byaddr,
fixed bin(31) byaddr )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
saxdtest: proc options( main );
dcl
1 eventHandler static
,2 e01 type event_without_data
init( start_of_document )
,2 e02 type event
init( version_information )
,2 e03 type event
init( encoding_declaration )
,2 e04 type event
init( standalone_declaration )
,2 e05 type event
init( document_type_declaration )
,2 e06 type event_without_data
init( end_of_document )
,2 e07 type event_with_namespace
init( start_of_element )
,2 e08 type event_with_namespace
init( attribute_name )
,2 e09 type event
init( attribute_characters )
,2 e10 type event_with_namespace
init( end_of_element )
,2 e11 type event_without_data
init( start_of_CDATA )
,2 e12 type event_without_data
init( end_of_CDATA )
,2 e13 type event_with_flag
init( content_characters )
,2 e14 type event_pi
init( processing_instruction )
,2 e15 type event
init( comment )
,2 e16 type event_namespace_dcl
init( namespace_declare )
,2 e17 type event_end_of_input
init( end_of_input )
,2 e18 type event
init( unresolved_reference )
,2 e19 type event_exception
init( exception )
;
dcl token char(45);
dcl rc fixed bin(31);
dcl i fixed bin(31);
dcl xml_document(8) char(300) var;
dcl xml_valid_msg(8) char(45) var;
dcl osr_ptr pointer;
dcl record char(80);
dcl osr_index fixed bin;
dcl osr_buf_tail fixed bin;
dcl temp_osr pointer;
dcl buf_size fixed bin(31) init(4096);
dcl rec_size fixed bin(31);
dcl osr_length fixed bin(31);
dcl buf_length fixed bin(31);
dcl eof fixed bin(31) init(0);
dcl osrin file input;
on endfile(osrin) begin;
eof = 1;
end;
/* read the entire PDS osr file into the buffer */
put skip list ('SAXDTEST: PL/I XML Validation sample ');
osr_length = buf_size;
osr_index = 0;
osr_buf_tail = 0;
rec_size = length(record);
osr_ptr = allocate(osr_length);
do while (eof = 0 );
read file(osrin) into(record);
osr_buf_tail += rec_size;
if osr_buf_tail > buf_size then
do;
buf_length = osr_length;
osr_length +=buf_size;
temp_osr = allocate(osr_length);
call plimove(temp_osr, osr_ptr, buf_length);
call plifree(osr_ptr);
osr_ptr = temp_osr;
osr_buf_tail = rec_size;
call plimove(osr_ptr+osr_index, addr(record), rec_size);
osr_index += rec_size;
end;
else
do;
call plimove(osr_ptr+osr_index, addr(record), rec_size);
osr_index +=rec_size;
end;
end;
/* Valid XMLFILE */
xml_document(1) = '<stockItem itemNumber="453-SR">'
|| '<itemName>Stainless steel rope thimbles</itemName>'
|| '<quantityOnHand>23</quantityOnHand>'
|| '</stockItem>';
xml_valid_msg(1) = 'Valid XMLFILE ';
/* Valid: the ITEMNAME element can be omitted */
xml_document(2) = '<stockItem itemNumber="453-SR">'
|| '<quantityOnHand>23</quantityOnHand>'
|| '</stockItem>';
xml_valid_msg(2) = 'Valid: the ITEMNAME element can be omitted.';
/* Invalid: missing attribute itemNumber */
xml_document(3) = '<stockItem>'
|| '<itemName>Stainless steel rope thimbles</itemName>'
|| '<quantityOnHand>23</quantityOnHand>'
|| '</stockItem>';
xml_valid_msg(3) = 'Invalid: missing attribute itemNumber.';
/* Invalid: unexpected attribute warehouse */
xml_document(4) = '<stockItem itemNumber="453-SR" warehouse="NY">'
|| '<itemName>Stainless steel rope thimbles</itemName>'
|| '<quantityOnHand>23</quantityOnHand>'
|| '</stockItem>';
xml_valid_msg4) = 'Invalid: unexpected attribute warehouse.';
/* Invalid: illegal attribute value 123-Ab */
xml_document(5) = '<stockItem itemNumber="123-Ab">'
|| '<itemName>Stainless steel rope thimbles</itemName>'
|| '<quantityOnHand>23</quantityOnHand>'
|| '</stockItem>';
xml_valid_msg(5) = 'Invalid: illegal attribute value 123-Ab.';
/* Invalid: missing element quantityOnHand */
xml_document(6) = '<stockItem itemNumber="074-UN">'
|| '<itemName>Stainless steel rope thimbles</itemName>'
|| '</stockItem>';
xml_valid_msg(6) = 'Invalid: missing element quantityOnHand.';
/* Invalid: unexpected element comment */
xml_document(7) = '<stockItem itemNumber="453-SR">'
|| '<itemName>Stainless steel rope thimbles</itemName>'
|| '<quantityOnHand>1</quantityOnHand>'
|| '<commnet>Nylon bristles</comment>'
|| '</stockItem>';
xml_valid_msg(7) = 'Invalid: unexpected element comment.';
/* Invalid: out-of-range element value 100 */
xml_document(8) = '<stockItem itemNumber="123-AB">'
|| '<itemName>Paintbrush</itemName>'
|| '<quantityOnHand>100</quantityOnHand>'
|| '</stockItem>';
xml_valid_msg(8) = 'Invalid: out-of-range element value 100';
do i = 1 to hbound(xml_document);; token = xml_valid_msg(i); call plisaxd( eventHandler, addr(token), addrdata(xml_document(i)), length(xml_document(i)), osr_ptr, 37 ); end; close file(osrin); call plifree(osr_ptr); end; start_of_document: proc( userToken ) returns( byvalue fixed bin(31) ) options( byvalue linkage(optlink) ); dcl userToken pointer; return(0); end; version_information: proc( userToken, xmlToken, TokenLength ) returns( byvalue fixed bin(31) ) options( byvalue linkage(optlink) ); dcl userToken pointer; dcl xmlToken pointer; dcl tokenLength fixed bin(31); return(0); end; encoding_declaration: proc( userToken, xmlToken, TokenLength ) returns( byvalue fixed bin(31) ) options( byvalue linkage(optlink) ); dcl userToken pointer; dcl xmlToken pointer; dcl tokenLength fixed bin(31); return(0); end; standalone_declaration: proc( userToken, xmlToken, TokenLength ) returns( byvalue fixed bin(31) ) options( byvalue linkage(optlink) ); dcl userToken pointer; dcl xmlToken pointer; dcl tokenLength fixed bin(31); return(0); end;
document_type_declaration:
proc( userToken, xmlToken, TokenLength )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl xmlToken pointer;
dcl tokenLength fixed bin(31);
return(0);
end;
end_of_document:
proc( userToken )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
put skip list( 'SAXDTEST: Document Successfully parsed ');
return(0);
end;
start_of_element:
proc( userToken, xmlToken, TokenLength,
nsPrefix, nsPrefixLength,
nsUri, nsUriLength )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl xmlToken pointer;
dcl tokenLength fixed bin(31);
dcl nsPrefix pointer;
dcl nsPrefixLength fixed bin(31);
dcl nsUri pointer;
dcl nsUriLength fixed bin(31);
return(0);
end;
attribute_name:
proc( userToken, xmlToken, tokenLength,
nsPrefix, nsPrefixLength,
nsUri, nsUriLength )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl xmlToken pointer;
dcl tokenLength fixed bin(31);
dcl nsPrefix pointer;
dcl nsPrefixLength fixed bin(31);
dcl nsUri pointer;
dcl nsUriLength fixed bin(31);
return(0);
end;
attribute_characters:
proc( userToken, xmlToken, TokenLength )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl xmlToken pointer;
dcl tokenLength fixed bin(31);
return(0);
end;
end_of_element:
proc( userToken, xmlToken, TokenLength,
nsPrefix, nsPrefixLength,
nsUri, nsUriLength )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl xmlToken pointer;
dcl tokenLength fixed bin(31);
dcl nsPrefix pointer;
dcl nsPrefixLength fixed bin(31);
dcl nsUri pointer;
dcl nsUriLength fixed bin(31);
return(0);
end;
start_of_CDATA:
proc( userToken )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
return(0);
end;
end_of_CDATA:
proc( userToken )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
return(0);
end;
content_characters:
proc( userToken, xmlToken, TokenLength, flags )
returns( byvalue fixed bin(31) )
options( nodescriptor, byvalue linkage(optlink) );
dcl userToken pointer;
dcl xmlToken pointer;
dcl tokenLength fixed bin(31);
dcl flags bit(8) aligned;
if flags = ''b then;
else
return(0);
end;
processing_instruction:
proc( userToken, piTarget, piTargetLength,
piData, piDataLength )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl piTarget pointer;
dcl piTargetLength fixed bin(31);
dcl piData pointer;
dcl piDataLength fixed bin(31);
return(0);
end;
comment:
proc( userToken, xmlToken, TokenLength )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl xmlToken pointer;
dcl tokenLength fixed bin(31);
return(0);
end;
namespace_declare:
proc( userToken, nsPrefix, nsPrefixLength,
nsUri, nsUriLength )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl nsPrefix pointer;
dcl nsPrefixLength fixed bin(31);
dcl nsUri pointer;
dcl nsUriLength fixed bin(31);
return(0);
end;
unresolved_reference:
proc( userToken, xmlToken, TokenLength )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl xmlToken pointer;
dcl tokenLength fixed bin(31);
return(0);
end;
exception:
proc( userToken, currentOffset, return_code, reason_code )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl currentOffset fixed bin(31);
dcl return_code fixed bin(31);
dcl reason_code fixed bin(31);
dcl validmsg char(45) based;
put skip list( userToken -> validmsg);
put skip list( lowercase( procname() )
|| ' return_code =' || hex(return_code)
|| ', reason_code =' || substr(hex(reason_code),5,4));
return(0);
end;
end_of_input:
proc( userToken, addr_xml, length_xml )
returns( byvalue fixed bin(31) )
options( byvalue linkage(optlink) );
dcl userToken pointer;
dcl addr_xml byaddr pointer;
dcl length_xml byaddr fixed bin(31);
return(0);
end;次の出力に、サンプル・プログラムの結果が示されています。 無効な文書の場合は、PLISAXD 組み込みサブルーチンが、リストされている戻りコードおよび理由コードを持つ XML 例外イベントを呼び出します。 それぞれの戻りコードおよび理由コードについて詳しくは、「XML System Services ユーザーズ・ガイドおよび解説書」を参照してください。
SAXDTEST: PL/I XML Validation sample SAXDTEST: Document Successfully parsed SAXDTEST: Document Successfully parsed Invalid: missing attribute itemNumber. exception return_code =00000018, reason_code =8613 Invalid: unexpected attribute warehouse. exception return_code =00000018, reason_code =8612 Invalid: illegal attribute value 123-Ab. exception return_code =00000018, reason_code =8809 Invalid: missing element quantityOnHand. exception return_code =00000018, reason_code =8611 Invalid: unexpected element comment. exception return_code =00000018, reason_code =8607 Invalid: out-of-range element value 100 exception return_code =00000018, reason_code =8803