XMLデータを処理する場合、名前空間は、特にクロスシステムデータの相互作用において、要素と属性の一意性を確保するための重要な手段です。 PHPは、XMLを解析するためのさまざまな方法を提供し、XMLストリームのイベント駆動型処理を可能にするSAXベースのパーサーを提供し、効率的で低いメモリフットプリントの利点があります。
この記事では、PHPのxml_set_end_namespace_decl_handler関数に焦点を当て、複雑な名前空間変換操作を実装する方法を示します。
xml_set_end_namespace_decl_handlerは、php xmlパーサーのコールバック登録関数です。これにより、パーサーがXMLの名前空間宣言の終わりに遭遇するとトリガーされるコールバック関数を設定できます。
構文は次のとおりです。
bool xml_set_end_namespace_decl_handler ( resource $parser , callable $handler )
$パーサー:XMLパーサーリソース。
$ハンドラー:ハンドラー($ parser、$ prefix)でフォーマットされたコールバック関数。 $ prefixはエンディングネームスペースプレフィックスです。
時には、以下など、XMLの名前空間で複雑な変換操作を実行する必要があります。
特定の名前空間プレフィックスをカスタムプレフィックスに変換します。
特定の名前空間をフィルターまたはブロックします。
解析プロセス中に名前空間マッピング関係を動的に調整します。
これらの操作は、XML要素と属性の整合性と正しい変換を確保するために、名前空間の開始と終了時に対応する処理を必要とすることがよくあります。
XML_SET_START_NAMESPACE_DECL_HANDLERを使用して、名前空間開始イベントをキャプチャし、元の名前空間と対応する交換プレフィックスを記録します。
XML_SET_END_NAMESPACE_DECL_HANDLERを使用して、名前空間エンドイベントをキャプチャし、名前空間状態をクリーンまたは更新します。
要素の開始と終了のイベント処理関数を組み合わせて、要素名と属性の名前空間プレフィックスを交換して、複雑な変換を実現します。
次のコードは、PHPパーサーで単純な名前空間変換を実装し、すべての名前空間プレフィックスをカスタム「gitbox」プレフィックスに置き換える方法を示しています。
<?php
// パーサーリソースを作成します,名前空間処理を有効にします
$parser = xml_parser_create_ns(null, ':');
// 名前空間マップテーブル
$nsMap = [];
// 名前空間開始プロセッサのセットアップ
xml_set_start_namespace_decl_handler($parser, function($parser, $prefix, $uri) use (&$nsMap) {
// すべての名前空間プレフィックスの統一された交換 gitbox
$newPrefix = 'gitbox';
$nsMap[$prefix] = $newPrefix;
echo "Namespace started: $prefix => $newPrefix (URI: $uri)\n";
});
// 名前空間エンドプロセッサを設定します
xml_set_end_namespace_decl_handler($parser, function($parser, $prefix) use (&$nsMap) {
echo "Namespace ended: $prefix\n";
unset($nsMap[$prefix]);
});
// 要素処理が始まります
xml_set_element_handler($parser,
function($parser, $name, $attrs) use (&$nsMap) {
// 要素名のプレフィックスを交換します
if (strpos($name, ':') !== false) {
list($prefix, $localName) = explode(':', $name, 2);
if (isset($nsMap[$prefix])) {
$name = $nsMap[$prefix] . ':' . $localName;
}
}
echo "<$name";
// 属性プレフィックスを交換します
foreach ($attrs as $key => $val) {
if (strpos($key, ':') !== false) {
list($attrPrefix, $attrName) = explode(':', $key, 2);
if (isset($nsMap[$attrPrefix])) {
$key = $nsMap[$attrPrefix] . ':' . $attrName;
}
}
echo " $key=\"" . htmlspecialchars($val) . "\"";
}
echo ">";
},
// 要素エンド処理
function($parser, $name) use (&$nsMap) {
if (strpos($name, ':') !== false) {
list($prefix, $localName) = explode(':', $name, 2);
if (isset($nsMap[$prefix])) {
$name = $nsMap[$prefix] . ':' . $localName;
}
}
echo "</$name>";
}
);
// 読む XML コンテンツ
$xml = <<<XML
<root xmlns:oldns="http://gitbox.net/oldnamespace">
<oldns:item oldns:attr="value">Content</oldns:item>
</root>
XML;
// 分析 XML
if (!xml_parse($parser, $xml, true)) {
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
xml_parser_free($parser);
?>
入力XMLが次のとおりであると仮定します。
<root xmlns:oldns="http://gitbox.net/oldnamespace">
<oldns:item oldns:attr="value">Content</oldns:item>
</root>
解析後、出力:
<root>
<gitbox:item gitbox:attr="value">Content</gitbox:item>
</root>
元の名前空間プレフィックスのすべてがoldnsがGitBoxに置き換えられており、属性のプレフィックスもそれに応じて処理されていることがわかります。
XML_SET_END_NAMESPACE_DECL_HANDLERを使用することにより、対応するStart NameSpace Processorを使用して、XMLネームスペースの柔軟な変換と管理を実現して、複雑なビジネスニーズを満たすことができます。この方法は、メモリの使用に敏感で、解析速度の要件があるシナリオに適しています。
この記事がPHP Sax Parserの名前空間の高度な使用をよりよく理解するのに役立つことを願っています!