【PHP8.x】xmlwriter_write_dtd_entity()関数の使い方
xmlwriter_write_dtd_entity関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
『xmlwriter_write_dtd_entity関数は…を実行する関数です』
xmlwriter_write_dtd_entity関数は、XML文書のDTD(文書型定義)内に、完全なエンティティタグを書き込む処理を実行する関数です。DTDにおけるエンティティとは、頻繁に使用する文字列や外部ファイルの内容などに短い名前を付けて、文書内で繰り返し利用可能にするための仕組みです。この関数を使用することで、プログラムによって動的にDTDを生成する際に、様々な種類のエンティティ宣言を追加できます。
関数の引数には、対象となるXMLWriterリソース、エンティティの名前、そしてエンティティの内容を指定します。内容を指定した場合は内部エンティティが定義されます。さらに、オプションの引数を用いることで、パラメータエンティティ(DTD内でのみ使用されるエンティティ)として定義したり、公開識別子やシステム識別子を指定して外部ファイルを参照する外部エンティティを定義したりすることも可能です。
この関数は、xmlwriter_start_dtd関数とxmlwriter_end_dtd関数の間で呼び出す必要があります。処理が成功した場合はtrueを、失敗した場合はfalseを返します。
構文(syntax)
1xmlwriter_write_dtd_entity($writer, "name", "content", false, "publicId", "systemId", "notationData");
引数(parameters)
XMLWriter $writer, string $name, string $content, bool $isParam = false, ?string $publicId = null, ?string $systemId = null, ?string $notationData = null
- XMLWriter $writer: 出力対象となるXMLWriterオブジェクト
- string $name: エンティティ名を指定する文字列
- string $content: エンティティの値を指定する文字列
- bool $isParam = false: パラメータエンティティの場合はtrueを指定するブール値
- ?string $publicId = null: 公開識別子を指定する文字列。未指定の場合はnull
- ?string $systemId = null: システム識別子を指定する文字列。未指定の場合はnull
- ?string $notationData = null: NOTATION宣言の場合のデータ部分を指定する文字列。未指定の場合はnull
戻り値(return)
bool
この関数は、XML文書にDTDエンティティを書き込むことに成功したかどうかを示す真偽値(trueまたはfalse)を返します。
サンプルコード
PHP XMLWriterでDTDエンティティを定義する
1<?php 2 3// XMLWriterオブジェクトを初期化します。 4// これはメモリ上にXMLを構築するために使用されます。 5$writer = xmlwriter_open_memory(); 6 7// XML出力を整形(インデント)するように設定します。 8xmlwriter_set_indent($writer, true); 9// インデントにスペース2つを使用するように設定します。 10xmlwriter_set_indent_string($writer, ' '); 11 12// XMLドキュメントを開始します。バージョンとエンコーディングを指定します。 13xmlwriter_start_document($writer, '1.0', 'UTF-8'); 14 15// DTD (Document Type Definition) の開始を宣言します。 16// ここでは、XML文書のルート要素名を "document" と仮定しています。 17// publicId と systemId は null を指定し、内部DTDセットを定義します。 18xmlwriter_start_dtd($writer, 'document', null, null); 19 20// --- 汎用エンティティの定義 --- 21 22// 1. 内部汎用エンティティの宣言 23// 例: <!ENTITY myInternalEntity "これは内部エンティティの内容です。"> 24// - $name: 'myInternalEntity' (エンティティ名) 25// - $content: 'これは内部エンティティの内容です。' (エンティティが展開される内容) 26// - $isParam: false (汎用エンティティのため) 27// - $publicId, $systemId, $notationData: null (内部エンティティのため) 28$result = xmlwriter_write_dtd_entity( 29 $writer, 30 'myInternalEntity', 31 'これは内部エンティティの内容です。' 32); 33if (!$result) { 34 echo "エラー: 内部汎用エンティティの書き込みに失敗しました。\n"; 35} 36 37// 2. 外部汎用エンティティ (SYSTEM IDのみ) の宣言 38// 例: <!ENTITY myExternalEntity SYSTEM "http://example.com/external.xml"> 39// - $name: 'myExternalEntity' 40// - $content: '' (外部エンティティの場合、内容は空文字列) 41// - $isParam: false 42// - $publicId: null 43// - $systemId: 'http://example.com/external.xml' (外部リソースのURIまたはパス) 44// - $notationData: null 45$result = xmlwriter_write_dtd_entity( 46 $writer, 47 'myExternalEntity', 48 '', // 外部エンティティの場合、内容は空文字列 49 false, 50 null, 51 'http://example.com/external.xml' 52); 53if (!$result) { 54 echo "エラー: 外部汎用エンティティ (SYSTEM IDのみ) の書き込みに失敗しました。\n"; 55} 56 57// 3. 外部汎用エンティティ (PUBLIC IDとSYSTEM ID) の宣言 58// 例: <!ENTITY myPublicExternalEntity PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 59// - $name: 'myPublicExternalEntity' 60// - $content: '' 61// - $isParam: false 62// - $publicId: '-//W3C//DTD HTML 4.01 Transitional//EN' (公開識別子) 63// - $systemId: 'http://www.w3.org/TR/html4/loose.dtd' (システム識別子) 64// - $notationData: null 65$result = xmlwriter_write_dtd_entity( 66 $writer, 67 'myPublicExternalEntity', 68 '', // 外部エンティティの場合、内容は空文字列 69 false, 70 '-//W3C//DTD HTML 4.01 Transitional//EN', 71 'http://www.w3.org/TR/html4/loose.dtd' 72); 73if (!$result) { 74 echo "エラー: 外部汎用エンティティ (PUBLIC IDとSYSTEM ID) の書き込みに失敗しました。\n"; 75} 76 77// --- パラメータエンティティの定義 --- 78 79// 4. 内部パラメータエンティティの宣言 80// 例: <!ENTITY % myParamEntity "これはパラメータエンティティの内容です。"> 81// - $name: 'myParamEntity' 82// - $content: 'これはパラメータエンティティの内容です。' 83// - $isParam: true (パラメータエンティティであることを示す) 84// - $publicId, $systemId, $notationData: null (内部エンティティのため) 85$result = xmlwriter_write_dtd_entity( 86 $writer, 87 'myParamEntity', 88 'これはパラメータエンティティの内容です。', 89 true // パラメータエンティティであることを示す 90); 91if (!$result) { 92 echo "エラー: 内部パラメータエンティティの書き込みに失敗しました。\n"; 93} 94 95// --- 非パースエンティティの定義 --- 96 97// 非パースエンティティを使用する前に、そのエンティティが参照する表記法 (NOTATION) を定義します。 98// 例: <!NOTATION gif SYSTEM "image/gif"> 99// - $name: 'gif' (表記法名) 100// - $publicId: null 101// - $systemId: 'image/gif' (表記法に関連するシステム識別子、MIMEタイプなど) 102xmlwriter_write_dtd_notation($writer, 'gif', null, 'image/gif'); 103 104// 5. 非パース汎用エンティティの宣言 (NDATAを使用) 105// 例: <!ENTITY myGifImage SYSTEM "image.gif" NDATA gif> 106// - $name: 'myGifImage' 107// - $content: '' (非パースエンティティの場合、内容は空文字列) 108// - $isParam: false 109// - $publicId: null 110// - $systemId: 'image.gif' (外部リソースのURI/パス、例: 画像ファイル) 111// - $notationData: 'gif' (事前に定義したNOTATION名を指定) 112$result = xmlwriter_write_dtd_entity( 113 $writer, 114 'myGifImage', 115 '', // 非パースエンティティの場合、内容は空文字列 116 false, 117 null, 118 'image.gif', // SYSTEM IDとしてリソースのURI/パスを指定 119 'gif' // 定義済みのNOTATION名を指定 120); 121if (!$result) { 122 echo "エラー: 非パース汎用エンティティの書き込みに失敗しました。\n"; 123} 124 125// DTDの宣言を終了します。 126xmlwriter_end_dtd($writer); 127 128// DTDを参照するXML文書のルート要素を開始します。 129xmlwriter_start_element($writer, 'document'); 130 // コメントを追加して、定義したエンティティの利用方法を示します。 131 xmlwriter_write_comment($writer, '以下は定義したエンティティの使用例です。'); 132 133 // 内部汎用エンティティの参照 (&myInternalEntity;) 134 xmlwriter_write_element($writer, 'internalContent', '&myInternalEntity;'); 135 136 // 外部汎用エンティティの参照 (&myExternalEntity;) 137 xmlwriter_write_element($writer, 'externalResource', '&myExternalEntity;'); 138 139 // PUBLIC ID付き外部汎用エンティティの参照 (&myPublicExternalEntity;) 140 xmlwriter_write_element($writer, 'publicExternalResource', '&myPublicExternalEntity;'); 141 142 // パラメータエンティティはDTD内部でのみ使用され、XML文書の要素内容としては直接参照できません。 143 // 非パースエンティティはエンティティとして参照されますが、XMLパーサは内容を処理しません。 144 xmlwriter_write_element($writer, 'binaryImageRef', '&myGifImage;'); 145 146xmlwriter_end_element($writer); // ルート要素 'document' を終了します。 147 148// XMLドキュメントの作成を終了します。 149xmlwriter_end_document($writer); 150 151// 生成されたXMLドキュメントの内容をメモリから取得し、出力します。 152echo xmlwriter_output_memory($writer); 153 154?>
xmlwriter_write_dtd_entity関数は、PHPのXMLWriter拡張機能を用い、XMLドキュメントのDTD(Document Type Definition)内にエンティティを定義します。エンティティとは、XML文書内で共通して使うテキストや外部リソースへの参照を簡潔に定義し、再利用性を高める仕組みです。
この関数は、XMLWriterオブジェクト($writer)にエンティティ定義を書き込みます。$nameでエンティティ名を、$contentでその実体内容を指定します。$isParamがtrueならパラメータエンティティ、falseなら汎用エンティティとして扱われます。外部リソースや表記法を指定するための引数も用意されており、$publicId、$systemId、$notationDataがそれぞれ公開識別子、システム識別子、表記法名に該当します。処理は成功時にtrue、失敗時にfalseを返します。
サンプルコードでは、まずxmlwriter_open_memory()でXMLWriterを初期化し、XML出力の整形設定を行います。次にxmlwriter_start_dtd()でDTDの記述を開始し、xmlwriter_write_dtd_entity関数を複数回使って、内部、外部、パラメータ、非パースといった様々な種類のエンティティをDTD内に定義しています。非パースエンティティでは、事前にxmlwriter_write_dtd_notationで表記法を定義する手順も示されます。これにより、XML文書の構造を柔軟に記述し、内容の再利用や外部リソースの参照を容易にします。最後にxmlwriter_end_dtd()でDTDを閉じ、XML文書の要素とエンティティ参照を書き込み、xmlwriter_output_memory()で生成されたXML全体を出力します。
xmlwriter_write_dtd_entity関数は、XML文書の構造を定めるDTD内で、再利用可能な「エンティティ」を宣言するために利用します。引数$isParamをtrueに設定するとDTD内部でのみ使用されるパラメータエンティティとなり、falseの場合はXML文書のコンテンツ内で&エンティティ名;のように参照可能な汎用エンティティとなります。外部エンティティを定義する際は、$contentは通常空文字列とし、$publicIdや$systemIdで外部リソースの識別子を指定します。非パースエンティティを用いる場合、$notationDataにはxmlwriter_write_dtd_notation関数で事前に定義した表記法名を指定する必要があります。これらの引数の組み合わせはエンティティの種類を決定するため非常に重要で、誤るとDTDが正しく解釈されません。関数は書き込みに失敗するとfalseを返しますので、実行結果の確認と適切なエラーハンドリングを強く推奨します。
PHP XMLWriterでDTDエンティティを定義する
1<?php 2 3/** 4 * XMLWriterエクステンションを使ってDTDエンティティを定義し、XMLドキュメントを生成するサンプルコードです。 5 * 6 * このスクリプトを実行するには、PHPにXMLWriterエクステンションがインストールされ、有効になっている必要があります。 7 * 多くのPHP環境ではデフォルトで有効になっていますが、もしPHPのバージョンアップ後などに動作しない場合は、 8 * php.iniファイルで `extension=xmlwriter` を有効にするか、システムのパッケージマネージャーで 9 * PHPのXML関連パッケージをインストールしてください(例: Debian/Ubuntuなら `sudo apt install php-xml`)。 10 */ 11function generateXmlWithDtdEntities(): string 12{ 13 // XMLWriterオブジェクトをメモリに開きます。 14 // ファイルに直接書き込む場合は `xmlwriter_open_uri('path/to/output.xml')` を使用します。 15 $writer = xmlwriter_open_memory(); 16 17 // 出力を整形するための設定。 18 xmlwriter_set_indent($writer, true); 19 xmlwriter_set_indent_string($writer, ' '); // 2スペースでインデント 20 21 // XMLドキュメントを開始します。バージョン1.0、エンコーディングUTF-8。 22 xmlwriter_start_document($writer, '1.0', 'UTF-8'); 23 24 // DTD (Document Type Definition) の開始。 25 // ルート要素は 'book' とし、内部DTDサブセットを定義します。 26 // publicIdとsystemIdはnullで、内部DTDを示します。 27 xmlwriter_start_dtd($writer, 'book', null, null); 28 29 // 内部DTDエンティティを書き込みます。 30 // 構文: <!ENTITY copyright "© 2023 My Company"> 31 // `$isParam` は `false` (一般エンティティ)。 32 xmlwriter_write_dtd_entity($writer, 'copyright', '© 2023 My Company', false); 33 34 // 外部DTDエンティティ(システム識別子のみ)を書き込みます。 35 // 構文: <!ENTITY legal SYSTEM "http://example.com/legal_notice.txt"> 36 // `$content` は外部ファイルから読み込まれるため空文字列。 37 // `$systemId` で外部リソースのURIを指定します。 38 xmlwriter_write_dtd_entity($writer, 'legal', '', false, null, 'http://example.com/legal_notice.txt'); 39 40 // パラメータエンティティを書き込みます。 41 // 構文: <!ENTITY % common.attributes "id CDATA #IMPLIED name CDATA #REQUIRED"> 42 // `$isParam` を `true` に設定することでパラメータエンティティとして定義されます。 43 xmlwriter_write_dtd_entity($writer, 'common.attributes', 'id CDATA #IMPLIED name CDATA #REQUIRED', true); 44 45 // DTD の終了。 46 xmlwriter_end_dtd($writer); 47 48 // XMLドキュメントのルート要素を開始します。 49 xmlwriter_start_element($writer, 'book'); 50 51 // DTDで定義した内部エンティティを参照する要素を書き込みます。 52 // '©right;' は、XMLパーサーによってDTDで定義された内容に展開されます。 53 xmlwriter_write_element($writer, 'title', 'PHP XMLWriter Example'); 54 xmlwriter_write_element($writer, 'author', 'Expert Programmer'); 55 xmlwriter_write_element($writer, 'notice', '©right;'); 56 57 // 外部エンティティの参照。XMLWriterは外部リソースを解決しないため、 58 // ここでは参照を記述するのみで、実際の展開はXMLパーサーが行います。 59 xmlwriter_write_element($writer, 'legal_info_ref', '&legal;'); 60 61 // パラメータエンティティは通常、DTD内部で他のDTD構造を定義するために使用され、 62 // XMLドキュメントのコンテンツに直接現れることはありません。 63 // そのため、ここでは直接的な参照の例は示しません。 64 65 // XMLドキュメントのルート要素を終了します。 66 xmlwriter_end_element($writer); // </book> 67 68 // XMLドキュメントを終了します。 69 xmlwriter_end_document($writer); 70 71 // メモリバッファから生成されたXML文字列を取得します。 72 $xmlString = xmlwriter_output_memory($writer); 73 74 // XMLWriterオブジェクトを閉じます(通常は不要ですが、明示的に閉じることができます)。 75 xmlwriter_close($writer); 76 77 return $xmlString; 78} 79 80// 関数を実行し、生成されたXMLを出力します。 81echo generateXmlWithDtdEntities();
xmlwriter_write_dtd_entity関数は、PHPのXMLWriterエクステンションを用いてXMLドキュメントのDTD(Document Type Definition)内にエンティティを定義する際に利用します。DTDエンティティとは、XML文書内で繰り返し使われるテキストのショートカットや、外部ファイルへの参照などを定義する仕組みです。これにより、XML文書の構造をより柔軟に、かつ簡潔に記述できます。
この関数は、最初の引数$writerで指定されたXMLWriterオブジェクトに対してエンティティを書き込みます。$name引数でエンティティの名前を、$contentにはそのエンティティが置き換えられる実際のテキスト内容を設定します。外部ファイルを参照するエンティティの場合、$contentは空文字列とし、外部リソースの場所は$systemId引数、場合によっては$publicId引数で指定します。$isParam引数をtrueにすると、DTD内で別のDTD構造を定義するために使用されるパラメータエンティティを定義できます。falseの場合は、XMLコンテンツ内で参照される一般エンティティとなります。$notationDataは、エンティティが特定の表記法に関連する場合に利用されます。関数は、処理が成功した場合はtrueを、失敗した場合はfalseを返します。
サンプルコードでは、著作権表示のような内部エンティティ、外部ファイルを参照する外部エンティティ、DTDの内部で属性定義の一部として利用するパラメータエンティティの3種類を定義しています。これらのエンティティは、対応するXML要素内で参照されることで、XMLパーサーによって定義された内容に展開されます。本関数を使用するためには、PHPにXMLWriterエクステンションがインストールされ、有効になっている必要があります。
このサンプルコードを実行する前に、PHPにXMLWriterエクステンションがインストールされ、有効になっているかを確認してください。xmlwriter_write_dtd_entity関数は、DTD(Document Type Definition)内でカスタムエンティティを定義するために用います。引数の$isParamをtrueにするとパラメータエンティティ、falseにすると一般エンティティとして定義される点が重要です。外部エンティティを定義する場合は$systemId等で外部リソースを指定し、$contentは空に設定します。DTDで定義したエンティティは、XMLWriter自身が展開するのではなく、後からXMLパーサーが解析する際に解決されます。外部エンティティの参照は、セキュリティ上のリスクにつながる場合があるため、利用には注意が必要です。