XML パーサ関数 XML
&reftitle.intro; XML (eXtensible Markup Language) は、Web における構造化された ドキュメント交換用のデータフォーマットです。XML は、World Wide Web consortium (W3C) で規定された規格です。XML に関する情報およ び関連する技術は、&url.xml; で参照することができます。 このPHPエクステンションは、James Clark氏の expatのサポートをPHPに付加します。 このツールキットは、XML ドキュメントの構文解析をしますが、 検証は行いません。3種類のソース 文字エンコーディング、 US-ASCII, ISO-8859-1 ,UTF-8 がPHPでサポートされます。UTF-16 はサポートさ れません。 この拡張モジュールは、XML パーサの作成 を行い、異なった XML イベントに関してハンドラ を定義します。各XMLパーサーには、設定可能な小数の パラメータ もあります。
&reftitle.required; このエクステンションは、expat を使用します。 これは、&url.expat;にあります。 expatに付属のMakefileは、デフォルトでライブラリを構築しません。こ れを行うmakeルールを次のように指定できます。 expat のソース RPM パッケージが &url.expat.rpm; にあります。
&reference.xml.configure;
&reftitle.runtime; &no.config;
&reftitle.resources;
<literal>xml</literal> xml_parser_createおよび xml_parser_create_ns により返された xmlリソースは、 このエクステンションにより提供された関数で使用される XMLパーサのインスタンスを参照します。
&reference.xml.constants;
イベントハンドラ XML イベントハンドラは次のように定義されます。 サポートされる XML ハンドラ ハンドラ設定用の PHP 関数 イベントの説明 xml_set_element_handler 要素イベントは、XML パーサーが開始または終了タグに出会うたび に発行されます。開始タグと終了タグについて別のハンドラがあり ます。 xml_set_character_data_handler 文字データは、タグの間の空白を含めて XML ドキュメントにおけ るほぼ全ての非マークアップ部分の内容です。XML パーサーは、 空白を加えたり削除したりしないことに注意してください。空白が 意味を有するかどうかを決めるのは、アプリケーション側の責任 です。 xml_set_processing_instruction_handler PHP プログラマは、既に処理用命令 (PI) に既に慣れているに違 いありません。<?php ?> は処理用命令であり、この場合、 php は "PI ターゲット"と呼ばれます。 これらの処理はアプリケーション依存ですが、全ての PI ターゲッ トが "XML" から始まることだけは、規定されています。 xml_set_default_handler 別のハンドラでしないことをデフォルトのハンドラで行います。 XML およびドキュメント型の宣言のようなことをデフォルトハンドラで 行います。 xml_set_unparsed_entity_decl_handler このハンドラは、処理されない (NDATA) エンティティの宣言用に コールされます。 xml_set_notation_decl_handler このハンドラは、表記の宣言用にコールされます。 xml_set_external_entity_ref_handler このハンドラは、XML パーサーが外部処理された通常のエンティティ への参照を見つけた際にコールされます。これは、例えば、ファ イルまたは URL への参照とすることが可能です。例としては、 外部エンティティ の例 を参照ください。
大文字変換(Case Folding) 要素ハンドラ関数は、その要素に大文字小文字を変換する (case-folded)の名前をつけることができます。 大文字変換(case-folding) は、XML標準により "大文字でないものは等 価な大文字に置換される一連の文字に適用されるプロセス" として定義 されています。言い替えると、XML に関しては単に大文字変換は大文字 にすることを意味します。 デフォルトで、ハンドラ関数に渡される全ての要素名は、大文字変換さ れます。この動作は、xml_parser_get_option およびxml_parser_set_option 関数でXMLパーサー 毎にそれぞれ問い合わせ、制御することが可能です。
エラーコード (xml_parse により返されるものとして) XMLエラーコードとして次のような定数が定義されています。: XML_ERROR_NONE XML_ERROR_NO_MEMORY XML_ERROR_SYNTAX XML_ERROR_NO_ELEMENTS XML_ERROR_INVALID_TOKEN XML_ERROR_UNCLOSED_TOKEN XML_ERROR_PARTIAL_CHAR XML_ERROR_TAG_MISMATCH XML_ERROR_DUPLICATE_ATTRIBUTE XML_ERROR_JUNK_AFTER_DOC_ELEMENT XML_ERROR_PARAM_ENTITY_REF XML_ERROR_UNDEFINED_ENTITY XML_ERROR_RECURSIVE_ENTITY_REF XML_ERROR_ASYNC_ENTITY XML_ERROR_BAD_CHAR_REF XML_ERROR_BINARY_ENTITY_REF XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF XML_ERROR_MISPLACED_XML_PI XML_ERROR_UNKNOWN_ENCODING XML_ERROR_INCORRECT_ENCODING XML_ERROR_UNCLOSED_CDATA_SECTION XML_ERROR_EXTERNAL_ENTITY_HANDLING
文字エンコーディング PHPのXML拡張機能は、異なった文字エンコーディング を通じてUnicode 文字セットをサポートします。ソースエンコーディング およびターゲットエンコーディング という2種類の文字エンコーディングがあります。 PHP におけるドキュメントの内部表現は、常に UTF-8でエンコードされます。 ソースエンコーディングは、XMLドキュメントが 構文解析された際に行わ れます。XML パーサの 作成を行う際に、ソースエンコードを指定することができます。 (このエンコーディングは、その XML パーサーが存在する間、後で変更す ることはできません)サポートされるソースエンコーディングは、 ISO-8859-1, US-ASCII , UTF-8 です。前の二つは、シングルバイトエンコー ディングです。これは、各文字がシングルバイトで表現されることを意 味します。UTF-8 は、1から4バイトの可変ビット 数(最大21ビット)で構成された文字をエンコードすることが可能です。 PHP で用いられるデフォルトのソースエンコーディングは、 ISO-8859-1です。 ターゲットエンコーディングは、PHPがデータをXMLハンドラ関数に 渡す時に行われます。あるXMLパーサが作成された際、ターゲットエン コーディングは、ソースエンコーディングと同様に設定されます。 しかし、これは、いつでも変更可能です。ターゲットエンコーディング は、タグ名と同様に文字データに作用し、命令を処理します。 XML パーサがソースエンコーディングが表現できる範囲の外側の文字に 出会った場合、エラーが返されます。 解釈するXMLドキュメントにおいてPHPが文字に出会った際に、選択した ターゲットエンコーディングで表現できない文字に出会った場合、問題 の文字は "降格" されます。現在、このことはこのような文字が疑問符 で置換されることを意味します。
&reftitle.examples; 以下にXMLドキュメントを処理するPHPスクリプトの例をいくつか示します。
XML エレメント構造の例 この最初の例は、あるドキュメント中のstart エレメントの構造をイン デントを付けて表示します。 XML エレメント構造を表示 ]]>
XMLタグのマッピングの例 XMLをHTMLにマップする この例は、XMLドキュメントのタグを直接HTMLタグにマップします。 "map array" にないエレメントは無視されます。もちろん、この例は、 特定の XML ドキュメント型を有する場合のみ動作します。 "B", "EMPHASIS" => "I", "LITERAL" => "TT" ); function startElement($parser, $name, $attrs) { global $map_array; if (isset($map_array[$name])) { echo "<$map_array[$name]>"; } } function endElement($parser, $name) { global $map_array; if (isset($map_array[$name])) { echo ""; } } function characterData($parser, $data) { echo $data; } $xml_parser = xml_parser_create(); // use case-folding so we are sure to find the tag in $map_array xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true); xml_set_element_handler($xml_parser, "startElement", "endElement"); xml_set_character_data_handler($xml_parser, "characterData"); if (!($fp = fopen($file, "r"))) { die("could not open XML input"); } while ($data = fread($fp, 4096)) { if (!xml_parse($xml_parser, $data, feof($fp))) { die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xml_parser)), xml_get_current_line_number($xml_parser))); } } xml_parser_free($xml_parser); ?> ]]>
XML 外部エンティティの例 この例は、XML コードに焦点を当てます。この例は、他のドキュメント をインクルードし処理するための外部エンティティリファレンスのハン ドラの使用法およびPIの処理方法、PIが含むコードに関する"信頼度" を定義する手段を説明します。 この例で使用される XML ドキュメントは、例題ファイル (xmltest.xml および xmltest2.xml) にあります。 外部エンティティの例 $name"; if (count($attribs)) { foreach ($attribs as $k => $v) { echo " $k=\"$v\""; } } echo ">"; } function endElement($parser, $name) { echo "</$name>"; } function characterData($parser, $data) { echo "$data"; } function PIHandler($parser, $target, $data) { switch (strtolower($target)) { case "php": global $parser_file; // If the parsed document is "trusted", we say it is safe // to execute PHP code inside it. If not, display the code // instead. if (trustedFile($parser_file[$parser])) { eval($data); } else { printf("Untrusted PHP code: %s", htmlspecialchars($data)); } break; } } function defaultHandler($parser, $data) { if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") { printf('%s', htmlspecialchars($data)); } else { printf('%s', htmlspecialchars($data)); } } function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId, $publicId) { if ($systemId) { if (!list($parser, $fp) = new_xml_parser($systemId)) { printf("Could not open entity %s at %s\n", $openEntityNames, $systemId); return false; } while ($data = fread($fp, 4096)) { if (!xml_parse($parser, $data, feof($fp))) { printf("XML error: %s at line %d while parsing entity %s\n", xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser), $openEntityNames); xml_parser_free($parser); return false; } } xml_parser_free($parser); return true; } return false; } function new_xml_parser($file) { global $parser_file; $xml_parser = xml_parser_create(); xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 1); xml_set_element_handler($xml_parser, "startElement", "endElement"); xml_set_character_data_handler($xml_parser, "characterData"); xml_set_processing_instruction_handler($xml_parser, "PIHandler"); xml_set_default_handler($xml_parser, "defaultHandler"); xml_set_external_entity_ref_handler($xml_parser, "externalEntityRefHandler"); if (!($fp = @fopen($file, "r"))) { return false; } if (!is_array($parser_file)) { settype($parser_file, "array"); } $parser_file[$xml_parser] = $file; return array($xml_parser, $fp); } if (!(list($xml_parser, $fp) = new_xml_parser($file))) { die("could not open XML input"); } echo "
";
while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d\n",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
echo "
"; echo "parse complete\n"; xml_parser_free($xml_parser); ?> ]]>
xmltest.xml ]> Title &plainEntity; a1b1c1 a2c2 a3b3c3 &systemEntity;
About this Document
]]>
This file is included from xmltest.xml: xmltest2.xml ]> &testEnt; ]]>
&reference.xml.functions;