8

外部ソースから取得した XML ドキュメントを PHP にロードする必要があります。XML はエンコーディングを宣言しておらず、 のような不正な文字を含んでいます&。XML ドキュメントをブラウザに直接ロードしようとすると、「テキスト コンテンツに無効な文字が見つかりました」などのエラーが表示されます。また、PHP でファイルをロードするときにも、次のような多くの警告が表示されxmlParseEntityRef: no name in EntityますInput is not proper UTF-8, indicate encoding ! Bytes: 0x9C 0x31 0x21 0x3C

XML の形式が正しくなく、XML エンティティに変換する必要がある不正な文字が含まれていることは明らかです。

これは、XML フィードが他の多くのユーザーから提供されたデータで構成されており、明らかにそれを取得する前に検証または再フォーマットされていないためです。

XML フィードの供給者と話したところ、彼らはコンテンツ プロバイダーにそれを整理させようとしているとのことですが、最初に入力を検証する必要があるため、これはばかげているように思えます。

PHP の DOMDocument 関数を使用するときに XML が問題をロードするように、エンコード エラーを修正し、不正な文字を XML エンティティに変換して XML を修正する必要があります。

私のコードは現在次のようになっています:

  $feedURL = '3704017_14022010_050004.xml';
  $dom = new DOMDocument();
  $dom->load($feedURL);

エンコードの問題を示す XML ファイルの例 (クリックしてダウンロード): feed.xml

XML エンティティに変換されていない文字を含む XML の例:

<?xml version="1.0"?>
<feed>
<RECORD>
<ID>117387</ID>
<ADVERTISERNAME>Test</ADVERTISERNAME>
<AID>10544740</AID>
<NAME>This & This</NAME>
<DESCRIPTION>For one day only this is > than this.</DESCRIPTION>
</RECORD>
</feed>
4

3 に答える 3

11

この問題を解決するには、XML ドキュメントをロードする前にDomDocument の回復プロパティをに設定します。TRUE

$dom->recover = TRUE;

このコードを試してください:

$feedURL = '3704017_14022010_050004.xml';
$dom = new DOMDocument();
$dom->recover = TRUE;
$dom->load($feedURL);
于 2012-02-14T18:10:05.493 に答える
8

不正なHTMLおよびXMLをクリーンアップするために使用できるTidyライブラリを使用してみてください http://php.net/manual/en/book.tidy.php

次のようなXMLを修正するための純粋なPHPソリューション:

<?xml version="1.0"?>
<feed>
<RECORD>
<ID>117387</ID>
<ADVERTISERNAME>Test < texter</ADVERTISERNAME>
<AID>10544740</AID>
<NAME>This & This</NAME>
<DESCRIPTION>For one day only this is > than this.</DESCRIPTION>
</RECORD>
</feed>

次のようになります:

  function cleanupXML($xml) {
    $xmlOut = '';
    $inTag = false;
    $xmlLen = strlen($xml);
    for($i=0; $i < $xmlLen; ++$i) {
        $char = $xml[$i];
        // $nextChar = $xml[$i+1];
        switch ($char) {
        case '<':
          if (!$inTag) {
              // Seek forward for the next tag boundry
              for($j = $i+1; $j < $xmlLen; ++$j) {
                 $nextChar = $xml[$j];
                 switch($nextChar) {
                 case '<':  // Means a < in text
                   $char = htmlentities($char);
                   break 2;
                 case '>':  // Means we are in a tag
                   $inTag = true;
                   break 2;
                 }
              }
          } else {
             $char = htmlentities($char);
          }
          break;
        case '>':
          if (!$inTag) {  // No need to seek ahead here
             $char = htmlentities($char);
          } else {
             $inTag = false;
          }
          break;
        default:
          if (!$inTag) {
             $char = htmlentities($char);
          }
          break;
        }
        $xmlOut .= $char;
    }
    return $xmlOut;
  }

これは、タグ内にあるかどうかに注意し、そうでない場合はhtmlentitiesを使用してテキストをエンコードする単純なステートマシンです。

これは大きなファイルではメモリを大量に消費するため、ストリームプラグインまたはプリプロセッサとして書き直すことをお勧めします。

于 2010-02-15T16:23:06.340 に答える
0

きちんとした拡張機能がオプションでない場合は、htmlpurifierを検討してください。

于 2015-09-17T21:46:48.167 に答える