UTF-8のファイルを読み込みShift_JISに変換して表示するには?

解決


ミチ  2004-10-21 20:40:51  No: 117113  IP: [192.*.*.*]

お世話になります。
文字コードがUTF-8のXMLファイルがあり、これをパースして、画面に出したいと思っています。
パースはできるのですが、コード変換でつまづきました。
過去ログを調べ、ADODB.Stream を使ってやってみたのですが、うまくいきませんでした。
http://madia.world.coocan.jp/vb/vb_bbs2/200308_03080100.html
(このログの、魔界の仮面弁士さんのソースです)
String型にデータをセットして、上記URLの関数で変換したのですが、
霪??贊?苺??莓艨???
このようになってしまいました。
このソースを利用するだけでは出来ないのでしょうか。

また、ADODB.Stream について詳しい説明のあるページがあれば教えてください。
よろしくお願いいたします。m(__)m

編集 削除
魔界の仮面弁士  2004-10-21 21:17:50  No: 117114  IP: [192.*.*.*]

> 文字コードがUTF-8のXMLファイルがあり、これをパースして、画面に出したいと思っています。
MSXMLを使ってパースすれば、文字コードを気にせずに済むかと。


> String型にデータをセットして、
この時点で既に妖しいですが…。(^^;
もしかして、2重に変換していませんか?

> 上記URLの関数で変換したのですが、
ファイルからの読込なら、処理としては、

1. Charset に "UTF-8" を指定。
2. Openメソッドを実行。
3. LoadFromFileメソッドで元ファイルを読み込み。
4. ReadTextメソッドでString型変数に読み込み。

とするだけですよね。数行で済むはずですよ。


> また、ADODB.Stream について詳しい説明のあるページがあれば教えてください。
MDAC SDK (ADOのヘルプ)を参照してみてください。

編集 削除
ミチ  2004-10-22 09:31:12  No: 117115  IP: [192.*.*.*]

魔界の仮面弁士さん、ありがとうございます。
本人様にレスしていただいて嬉しいです^^

> MSXMLを使ってパースすれば、文字コードを気にせずに済むかと。
えっ…!そうなんですか??

> > String型にデータをセットして、
> この時点で既に妖しいですが…。(^^;
> もしかして、2重に変換していませんか?
String型の変数に、MSXML2.IXMLDOMElement.firstChild.Text で取得したものをセットしています。

文字化けの状況としては、なにもせずこのまま表示すると、"〜"の文字が"?"に化けてしまいます。
今のところ判明しているのは、"〜"の文字だけです。
もしかしてこれって他の原因でしょうか?

> ファイルからの読込なら、処理としては、
XMLをファイルをDOMで直接パースしたいので、ファイルから読み込む方法は現在考えておりません。

何か良い方法があったら教えてください。
よろしくお願いします・・・。

編集 削除
魔界の仮面弁士  2004-10-24 22:32:36  No: 117116  IP: [192.*.*.*]

>> MSXMLを使ってパースすれば、文字コードを気にせずに済むかと。
> えっ…!そうなんですか??
XMLファイルをloadメソッドで読み込めば、<?xml version="1.0" encoding="UTF-8"?>の部分を認識して、適切な文字コードのファイルとして読み込まれますよ。
特に今回はUTF-8なので、この宣言が無くても正しく認識されるでしょう。


> 文字化けの状況としては、なにもせずこのまま表示すると、"〜"の文字が"?"に化けてしまいます。
下記のコードでは、ChrW(&HFF5E) の「〜」が表示されます。
    Dim S As String
    Dim x As MSXML2.DOMDocument
    Set x = New DOMDocument40
    x.loadXML "<a/>"
    x.documentElement.Text = "〜"
    S = x.documentElement.firstChild.Text
    MsgBox Hex(AscW(S)) & ":" & S, vbInformation

> もしかしてこれって他の原因でしょうか?
"WAVE DASH" と "FULLWIDTH TILDE" の違いとか…。
http://park3.wakwak.com/~ozashin/sw_tips/webapp_tips/sjis_charset.html

>> ファイルからの読込なら、処理としては、
> XMLをファイルをDOMで直接パースしたいので、ファイルから読み込む方法は現在考えておりません。
あれ? どういう事でしょうか?
「ファイルを」パースしたいのに、「ファイルから読み込む方法」が使えないのですか?

編集 削除
ミチ  2004-10-25 18:31:43  No: 117117  IP: [192.*.*.*]

魔界の仮面弁士さん、ありがとうございます。

> "WAVE DASH" と "FULLWIDTH TILDE" の違いとか…。
http://park3.wakwak.com/~ozashin/sw_tips/webapp_tips/sjis_charset.html

このページが参考になりました。
原因はこれだったのですね。
性能は悪くなりますが、0x301Cを0xFF5Eに変換することで対処しました。

> 下記のコードでは、ChrW(&HFF5E) の「〜」が表示されます。
この例だと、Shift-JISなので表示されるのでしょうね。
UTF-8では「〜」は&H301Cでした。これを表示させると案の定「?」に化けました…。

> 「ファイルを」パースしたいのに、「ファイルから読み込む方法」が使えないのですか?
書き方に語弊がありましたね…(^^;
DOMでパースしたいので、それ以外のファイル読み込みはしない…ということでした。申し訳ありません。

魔界の仮面弁士さんのおかげで解決することができました。
本当にありがとうございました。

編集 削除
ミチ  2004-10-25 18:32:16  No: 117118  IP: [192.*.*.*]

解決しました。

編集 削除
魔界の仮面弁士  2004-10-25 19:40:12  No: 117119  IP: [192.*.*.*]

> UTF-8では「〜」は&H301Cでした。

それは UTF-16 では?

UTF-8 の場合、各文字のバイナリ範囲は
  0xxx xxxx(2進数) → 1バイト文字
  10xx xxxx(2進数) → (複数バイト文字の)2バイト目以降
  110x xxxx(2進数) → 2バイト文字の 1バイト目
  1110 xxxx(2進数) → 3バイト文字の 1バイト目
のように定義されていますので、&H30 (0011 0000) や
&H1C (0001 1100) で始まる文字は、存在しないかと。


> これを表示させると案の定「?」に化けました…。
Unicode対応コントロールなどを使えば、化けずに表示させられるかと。

編集 削除
魔界の仮面弁士  2004-10-25 21:08:24  No: 117120  IP: [192.*.*.*]

# 誤解をうむかな…。

> のように定義されていますので、&H30 (0011 0000) や
> &H1C (0001 1100) で始まる文字は、存在しないかと。

「〜で始まる2バイト文字」は存在しない、という事ですね。m(_ _)m

UTF-8テキストにおいては、301C や 1C30 というデータの並びは、
単一の文字ではなく、2つの1バイト文字として認識されます。
http://www.unicode.org/charts/PDF/U0000.pdf

30 は、『0』DIGIT ZERO。
1C は、「制御コードFS」file separator/INFORMATION SEPARATOR FOUR。


なお、今回問題となった「〜」の文字は、UTF-8の場合には、
  U+301C "WAVE DASH"       → E3 80 9C
  U+FF5E "FULLWIDTH TILDE" → EF BD 9E
となっているはずです。


なお、ADODB.Streamのテキストモードで読み込んで、それを
.ReadText()で読む場合や、MSXML2のloadXMLメソッド等で読み込んで、
それを .xml や .text 等で読む場合、元ファイルの文字コードが
何であったとしても、文字コードは統一され、最終的には
VB の標準的な String型に変換される事になりますので、通常は、
String型の変数に、 EF BD 9E などのバイトの並びが渡される事はありません。

編集 削除
ミチ  2004-10-29 14:41:41  No: 117121  IP: [192.*.*.*]

魔界の仮面弁士さん、補足コメントありがとうございます。
#レスが遅くなってすみません…。

うーん、難しいですね…。文字コード問題。
VBで読み込んだらString型になるのは理解しました。そして、標準コントロールではUnicodeは表示できないのですね。
String型で保持してある、問題の文字("〜"など)を含む文字列において、
Replace関数でChrW(&H301C)を"〜"に変換して、解決できました。

これで良かったのかな…?
とりあえず問題もなさそうなので、これでいってみます。
ありがとうございました。

編集 削除