PHPのXML_PARSE()関数を使用してXMLデータを解析する場合、解析は無効または不正なXMLタグのためにしばしば失敗します。この状況は、ユーザーが入力したXML文字列、または信頼できないソース(外部APIなど、サードパーティによってアップロードされる)からのデータで特に一般的です。この記事では、これらのエラーを優雅に処理する方法を説明し、解析エラーを避けるために一般的な問題を自動的に修正しようとします。
XML_PARSE()は、イベント駆動型の方法でXMLデータを解析するPHPのXMLパーサー(Expat Libraryに基づく)の一部です。
$parser = xml_parser_create();
xml_parse($parser, $xmlString, true);
xml_parser_free($parser);
$ XMLSTRINGのXMLが無効である場合、関数はFALSEを返し、 XML_GET_ERROR_CODE()およびXML_ERROR_STRING()を介して詳細なエラー情報を取得できます。
ラベルは閉じられていません:
<note><to>Tove</to><from>Jani</note>
特殊文字は逃げられません:
<message>5 < 10 & 7 > 3</message>
不正なキャラクターまたは違法なエンコーディング
間違ったネストされた構造
標準以外または腐敗したXMLに対処する必要がある場合は、いくつかの戦略を使用して、処理または修正することができます。
PHPのDomdocumentクラスは、XMLをロードするときにエラー報告を無効にすることを可能にし、したがって、障害トレラントにしようとします。
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$success = $doc->loadXML($xmlString);
if (!$success) {
foreach (libxml_get_errors() as $error) {
echo "修復の提案:" . $error->message . "\n";
}
libxml_clear_errors();
}
この方法は修正されないかもしれませんが、何がうまくいかなかったかを知ることができます。
XMLの構造がわかっている場合は、定期的または文字列交換で修正できます。
function sanitizeXml($xml) {
// 違法なものを交換します & キャラクター
$xml = preg_replace('/&(?!amp;|lt;|gt;|quot;|apos;)/', '&', $xml);
// 必要に応じて、他のルールを完了できます
return $xml;
}
ログの保存、データ状態のマークなど、XMLの解析を関数にラップし、処理が失敗したら、処理をダウングレードすることができます。
function safeXmlParse($xmlString) {
$parser = xml_parser_create();
if (!xml_parse($parser, $xmlString, true)) {
$error = xml_error_string(xml_get_error_code($parser));
$line = xml_get_current_line_number($parser);
error_log("XML分析に失敗しました: $error at line $line");
// オプション:管理者に通知するか、レコードをスキップします
return false;
}
xml_parser_free($parser);
return true;
}
URL https://api.m66.net/feedからXMLデータを取得するとします:
$url = "https://api.m66.net/feed";
$xmlData = file_get_contents($url);
$xmlData = sanitizeXml($xmlData);
if (!safeXmlParse($xmlData)) {
echo "これを解析できません XML データ,ログに記録されています。\n";
} else {
echo "XML 成功した分析!\n";
}
特に混乱するXMLのために、 Tidy 、 Xmllint 、PythonのBeautifulSoupなどの外部ツールを使用して、クリーンアップしてからPHPにインポートすることができます。
XML解析エラーを処理するための鍵は、前処理 +エラートレランス +フォールトトレランス回復メカニズムにあります。 XML_PARSE()は基本が厳密なXML解析方法ですが、不規則なXMLとDOM、LIBXML、手動修理戦略、その他の方法との互換性を大幅に改善できます。
次回、「神秘的なXML解析障害」に直面しているときは、これらの方法を試すこともできます!