3

クイックバージョン:

不正なファイル、特にエスケープされていない文字が原因で XMLReader によってスローされたエラーをキャッチして処理する標準的な (革新的な? 何​​か?) 方法は何ですか? Tidy(など)を先取りすることは、非常に魅力的なオプションではありません。問題のあるノードをスキップして、すぐに移動する方法を知っている人はいますか?

記述バージョン:

XML が適切に形成されていない場合、XML ではないことは誰もが知っていますが、正直なところ、XML は起こります。クライアントは、mysql に読み込む必要がある大量の (50 ~ 100 MB 以上) xml ファイルを定期的に取り込みます。XMLReader は当然の選択であり、必要に応じて適切に機能するラッパーを作成しました。

時折、エラーが発生し、read() がインポートの強制終了に失敗します。ほとんどの場合、エスケープされていない文字 ("&" など) がすべてをつまずかせます。ほとんどの場合、クライアントにデータ プロバイダーに電話してもらい、欠陥のあるファイルを修正するよう要求するだけです。残念ながら、データ プロバイダーは常に義務付けられているわけではなく、タイムリーでもありません。単純にエラーをキャッチして、次のノードに進むことができれば素晴らしいことです。

私はこれを読んだりクラックしたりするのにかなりの時間を費やしましたが、熟読する価値のあるものを見つけることができません. 明らかな何かが欠けていますか?

この SO の質問は有望に思えましたが、結果が得られませんでした。1 を渡すと、Reader に回復を要求する必要があるように見えますが、試行や別のエラー メッセージなどが表示されないだけです。アプローチの概要を示す関連コードは次のとおりです。

$xml->open($file, null, LIBXML_NOERROR | LIBXML_NOWARNING | 1);

Tidy でいつでも前処理できますが、もっと良い方法があるはずです。

現在のノードのロジックが完了した後、次の Read() を try/catch でスニッフィングするなど、さらに「クリエイティブな」アプローチを検討しましたが、せいぜい不器用に思えます。また、ノード間を移動し、エラー処理を組み込むのに役立つカスタム/ラッパー関数を使用して Read() をエミュレートする可能性があるようですが、物事を単純化しすぎていると感じています。

要約すると、read() が失敗した場合、どうすればエラーをキャッチして先に進むことができるでしょうか? 発生しているエラー (少なくとも XMLReader がスローしたメッセージ) を確認できる可能性はありますか?

$xml = new XMLReader();
$xml->open($file);

while ($xml->read()) {  

}
4

3 に答える 3

3

これは XML リーダーであり、XML を読み取るように作られています。無効な XML は XML ではなく、XML リーダーで読み取ることができません。それは単純なことです。

インポートする前にファイルに対して実行xmllintして有効かどうかを確認するか、正しいことを行ってデータ プロバイダーに有効な xml を生成するように指示してください。

于 2011-03-01T08:58:46.110 に答える
2

あなたの質問の「エラーを見る」部分について:

http://php.net/manual/en/function.libxml-use-internal-errors.php この設定がデフォルトの false 値の場合、無効な XML に対して PHP 警告がトリガーされます。言い換えれば、あなたはそれを見たはずです:p あなたはただ注意を払っていなかったか、PHP 警告をあなたから隠している設定またはカスタムエラーハンドラーを有効にしていました.

上記の関数を true で呼び出すと、警告は生成されず、代わりに、この関数によって返される内部配列にエラーが蓄積されます。

http://www.php.net/manual/en/function.libxml-get-errors.php

「進む」部分については、cweiske が正しく、実行できないことを残念に思います。いくつかのツールを使用して XML のエラーを事前に選別し (XMLReader で解析することもできます)、見つかったエラーを修正することができます。つまり、無効な文字を削除/置換しますが、修正されたデータの解析を再開する必要があります。

于 2012-11-28T16:21:22.177 に答える
1

私は同じ問題に遭遇しました。ストリーム フィルターを使用すると、XMLReader にフィードする前に XML を修正できます。

このHTML から XML へのフィルターはこれを行います。として使用します

$dsn = "php://filter/read=htmltoxml.entities/resource=" . $url;
$xml = XMLReader::open($dsn);
于 2014-06-26T10:54:31.617 に答える