1. ホーム
  2. ハイパーリンク

[解決済み】HTMLエンコーディングの問題 - " " の代わりに "Â" 文字が表示される。

2022-04-05 01:27:46

質問

レガシーアプリの動作がおかしくなってきました。 このアプリは大量のHTMLを生成し、ActivePDFでPDFレポートに変換しています。

このような流れになります。

  1. 置き換えたいトークン(例:"~CompanyName~"、"~CustomerName~"など)を含むHTMLテンプレートをDBから引っ張ってきてください。
  2. トークンを実データに置き換える
  3. HTMLタグの属性値をプロパティフォーマットする簡単な正規関数でHTMLを整頓する(ActivePDFのレンダリングエンジンは属性値の周りにシングルクォート以外のものを嫌うので、クォーテーションマークなどを確実にする)。
  4. PDFを作成するウェブサービスにHTMLを送ります。

その混乱のどこかで、HTMLテンプレートからのノンブレーキングスペース(   がISO-8859-1としてエンコードされているため、ブラウザ(FireFox)で文書を表示すると、""文字として誤って表示されます。) ActivePDFはこれらのUTF8でない文字を吐き出してしまいます。

質問:この問題がどこから発生しているのか分からないし、それを調査する時間もないので、悪い文字を再エンコードするか、検索して置き換える簡単な方法はないでしょうか? 私が作ったこの小さな関数を通して送信してみましたが、これは <ストライク は、すべてをゴブレットグックに変えてしまう は何も変わりません。

Private Shared Function ConvertToUTF8(ByVal html As String) As String
    Dim isoEncoding As Encoding = Encoding.GetEncoding("iso-8859-1")
    Dim source As Byte() = isoEncoding.GetBytes(html)
    Return Encoding.UTF8.GetString(Encoding.Convert(isoEncoding, Encoding.UTF8, source))
End Function

何かアイデアはありますか?

EDITです。

今のところ、これで何とかなっていますが、良い解決策とは到底思えません。

Private Shared Function ReplaceNonASCIIChars(ByVal html As String) As String
    Return Regex.Replace(html, "[^\u0000-\u007F]", "&nbsp;")
End Function

解決方法は?

<ブロッククオート

この混乱のどこかで、HTML テンプレートからの非改行スペース (s) が ISO-8859-1 としてエンコードされているため、それらが "♪" 文字として誤って表示されているのです。

それならISO-8859-1ではなく、UTF-8にエンコードしているはずです。ISO-8859-1では改行されていないスペースは0xA0バイトです。UTF-8にエンコードすると0xC2,0xA0となり、(間違って)ISO-8859-1とみなしてしまうと、以下のようになります。 " " . このバイトには、あなたが気づいていないかもしれない末尾のnbspが含まれています。このバイトがない場合、他の何かがあなたのドキュメントを傷つけており、それを見つけるためにさらに上を見る必要があります。

正規表現、テンプレはどうなってるの?もし、あなたの &nbsp; の文字列は、(正しく)U+00A0 NON-BREAKING SPACE 文字に変換されています。もしそうなら、テンプレートを DOM でネイティブに処理し、ASCII エンコーディングを使って非 ASCII 文字を文字参照として保持するようにシリアライズを依頼すればよいのです。そうすれば、常に危険なビジネスであるHTML自体の正規表現の後処理を行う必要がなくなります。

まあとにかく、今のところ、以下のいずれかをドキュメントの <head> を実行し、ブラウザで正しく表示されるかどうかを確認します。

  • HTML4の場合。 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  • HTML5用。 <meta charset="utf-8">

それができていれば、残った問題はActivePDFのせいです。