巨大な XML ファイルを解析しようとしている PHP スクリプトがあります。これを行うために、私は XMLReader ライブラリを使用しています。解析中に、次のエンコード エラーが発生しました。
入力が適切な UTF-8 ではありません。エンコーディングを指定してください! バイト: 0xA0 0x32 0x36 0x30
それらが悪い文字を含むレコードをスキップする方法であるかどうかを知りたい.
ありがとう!
まず、XMLファイルが実際にUTF-8でエンコードされていることを確認してください。そうでない場合は、の2番目のパラメーターとしてエンコーディングを指定しますXMLReader::open()
。
エンコーディングエラーがUTF-8ドキュメントの実際の不正な形式のバイトシーケンスによるものであり、PHP> 5.2.0を使用している場合は、ビットマスクとして次の3番目のパラメータに渡すLIBXML_NOERROR
か(エラーレベルに応じて)できます。LIBXML_NOWARNING
XMLReader::open()
$xml = new XMLReader();
$xml->open('myxml.xml', null, LIBXML_NOERROR | LIBXML_NOWARNING);
PHP> 5.1.0を使用している場合は、libXML
エラー処理を微調整できます。
// enable user error handling
libxml_use_internal_errors(true);
/* ... do your XML processing ... */
$errors = libxml_get_errors();
foreach ($errors as $error) {
// handle errors here
}
libxml_clear_errors();
前の2つの回避策で、エラーが発生した場合に実際にXMLReader
読み取りを続行できるのか、それともエラー出力を抑制するだけなのかは、実際にはわかりません。しかし、試してみる価値はあります。
コメントへの返信:
libXML
(1)を定義しますXML_PARSE_RECOVER
が、ext/libxmlはこの定数をPHP定数として公開しません。おそらく、整数値1
を$options
パラメーターに渡すことが可能です。
$xml = new XMLReader();
$xml->open('myxml.xml', null, LIBXML_NOERROR | LIBXML_NOWARNING | 1);
XMLReader があなたに言っていることに耳を傾けます。多くのエンコーディングは ASCII のスーパーセットであるため、(たとえば) UTF-8 と ISO-8859-1 は、最初の 128 コード ポイントで ASCII と同一です。ファイルが実際には ISO-8859-1 としてエンコードされている可能性がありますが、ほとんどすべての文字は、その文字セットの下位の ASCII 半分からのものです。その場合、XML のデフォルトのエンコーディングである UTF-8 を使用することで、エラーが発生します。
ISO-8859-1 では、バイト シーケンス0xA0 0x32 0x36 0x30
は完全に有効です。改行しないスペースの後に '2'、'6'、'0' が続きます。
XMLファイルの構造が非常に単純な場合は、XMLファイルを「事前フィルタリング」して、間違ったレコードを削除(またはさらに適切に修正)することができます。
レコードごとに読み取り、フィルター処理されたxmlファイルを書き出してから、フィルター処理されたファイルを処理します。
$xml = file_get_contents('myxml.xml'); $xml = preg_replace('/[\x0-\x1f\x7f-\x9f]/u', ' ', $xml); // 以下の $xml を解析します