UnicodeでDOMするには

解決


taktak  2008-04-03 15:09:37  No: 139442  IP: 192.*.*.*

ASPで以下のようにDOMを使っているんですが、ShiftJIS範囲外の文字(Unicodeの外字)を代入しようとすると「&#60336」などに変換されてしまします。DOMをUnicodeで行うことは可能でしょうか?
Dim xDoc
Set xDoc = Server.CreateObject("MSXML2.DOMDocument") 
xDoc.async = False
xDoc.validateOnParse = False
xDoc.load("c:\hoge.xml")
xDoc.SelectSingleNode(sXPath).Text = "あああ"
xDoc.save("c:\hogehoge.xml")

ご教授お願いします。

編集 削除
魔界の仮面弁士  2008-04-03 20:37:18  No: 139443  IP: 192.*.*.*

> 「&#60336」などに変換されてしまします。
妙ですね。"" ならわかりますが、"&#60336" ですか…。
もしかして、どこかで別の変換処理をかけていませんか?

もし、 や  なのだとしたら、それは XML 上では
ChrW(&HEBB0) を意味する表現です。
それとも、元の文字は ChrW(&HEBB0) では無かったのでしょうか?


> DOMをUnicodeで行うことは可能でしょうか?
ファイルの入出力の際の文字コードが何であるにせよ、
DOM そのものは常に、Unicode で処理される仕様です。


> Set xDoc = Server.CreateObject("MSXML2.DOMDocument")
ASP 環境では、FreeThreadedDOMDocument を使いましょう。


> xDoc.save("c:\hogehoge.xml")
Const adTypeText = 2
Const adSaveCreateOverWrite = 2
With Server.CreateObject("ADODB.Stream")
  .Type = adTypeText
  .Charset = "UTF-8"
  .Open
  .WriteText xDoc.XML
  .SaveToFile "c:\hogehoge.xml", adSaveCreateOverWrite
  .Close
End With

とか。

編集 削除
taktak  2008-04-04 10:36:39  No: 139444  IP: 192.*.*.*

魔界の仮面弁士様、解説ありがとうございます。
>妙ですね。"" ならわかりますが、"&#60336" ですか…。
大文字変換を行ってました。もう一度正確に書きます。
UnicodeのED36(ShiftJIS範囲外の文字)をDOMであるタグに代入すると、
結果作成されたXMLファイルにはと値が代入されてしまいます。
私が結果として求めているのは、ED36の文字そのものなのですが、
解決策はありますでしょうか。よろしくお願いします。

編集 削除
魔界の仮面弁士  2008-04-04 10:37:41  No: 139445  IP: 192.*.*.*

> 解決策はありますでしょうか。
それは既に書いたはずですが、それでも駄目だったのでしょうか?

編集 削除
魔界の仮面弁士  2008-04-04 10:41:36  No: 139446  IP: 192.*.*.*

> と値が代入されてしまいます。
"" ではなく、
"" ですか?


だとすると、そもそも DOM に渡すデータが化けているような気がします。
DOM に渡しているデータを再検証してみてください。たとえば、
  .Text = ChrW(&HED36)
というデータを渡しているつもりで、実際には
  .Text = ""
になっていたりはしませんか?

編集 削除
taktak  2008-04-04 11:46:44  No: 139447  IP: 192.*.*.*

>だとすると、そもそも DOM に渡すデータが化けているような気がします。
DOMに渡している文字は入力画面のテキストエリア(t_data)で入力した文字をPOSTした値で、
sData = Request.Form("t_data")
〜中略〜
.Text = sData
と代入しています。
これじゃダメってことは、文字コードに変換する必要があるのでしょうか。

編集 削除
魔界の仮面弁士  2008-04-04 12:01:42  No: 139448  IP: 192.*.*.*

> sData = Request.Form("t_data")
この時点で、sData の内容が化けていないかどうかを検証してください。

sData = CStr(sData)
For N = 1 To Len(sData)
  S = Mid(sData, N, 1)
  Response.Write "<div>"
  Response.Write Hex(AscW(S))
  Response.Write " = " & S
  Response.Write "</div>"
Next

ここで問題が無いなら、DOM 側の問題かも知れませんが、この時点で
化けているのだとしたら、DOM の使い方を疑う前に、Web ページの構成や
文字コード設定などを見直す必要があるかも知れません。

編集 削除
taktak  2008-04-04 12:52:35  No: 139449  IP: 192.*.*.*

入力画面に1文字(ED36)を入力し検証しました。
結果Hex(AscW(S))の部分でエラーが出たので、
Response.Write len(sData)
Response.Write Hex(AscW(sData))
としたところ、
8
26
となりました。確かにこの時点であやしいです。魔界の仮面弁士様のご指摘とおりWebページの構成や文字コードの設定なのでしょうか。

ちなみに1文字(あ)を入力し
Response.Write len(sData)
Response.Write Hex(AscW(sData))
とすると
1
3042
と期待通りの結果が得られました。

編集 削除
魔界の仮面弁士  2008-04-04 13:13:35  No: 139450  IP: 192.*.*.*

> 8
> 26
> となりました。
&H26 といえば、"&" の文字ですね。
Len = 8 ですし、ほぼ間違いなく "&#60336;" になっていますね。


> Webページの構成や文字コードの設定なのでしょうか。
以下の点を確認し、必要であれば修正してみてください。

(1) ASP ファイルの文字コードは UTF-8 にしていますか?
  それとも Shift_JIS ですか?

(2) ASP の @CodePage は 65001(UTF-8) にしていますか?
  それとも 932 (Shift_JIS) ですか?
  あるいは、未設定ですか?

(3) Session.CodePage は、何に設定してありますか?

(4) HTTP レスポンスヘッダの Content-Type に、charset 指定がありますか?

(5) UTF-8 を処理できないような、旧式のブラウザから送出されていませんか?

編集 削除
魔界の仮面弁士  2008-04-04 13:16:47  No: 139451  IP: 192.*.*.*

もうひとつ。

(6) meta タグで、http-equiv="Content-Type" の content による
  charset 指定を行ってありますか?

--

まず、これらをすべて UTF-8 に切り替えた上で、現象が再現するかを確認してみてください。
限定的には Shift_JIS との混在も可能ですが、UTF-8 に統一しておいた方が、
問題の切り分けが楽になるかと思います。

編集 削除
taktak  2008-04-04 13:38:20  No: 139452  IP: 192.*.*.*

>以下の点を確認し、必要であれば修正してみてください。
丁寧な解説ありがとうございます。結局のところASPファイルには
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=Shift-JIS">
くらいしか設定していません。ちょっと調べてUTF-8に書き換えてから検証をやってみます。文字コードなどにもうとくてご迷惑かけます。

編集 削除
taktak  2008-04-04 15:22:12  No: 139453  IP: 192.*.*.*

ASPファイルをUTF-8化したつもりで検証を行ったところ。今度は何も書き込まれなくなりました。どこぞやのページにUTF-8はRequest.Formが動作しないとありましたが、それが原因でしょうか。ちなみにUTF-8の部分をUTF-16に変えて検証したところ、書込はされるものの内容は「&amp;#60726;」になります。
<%@Language="VBScript" CODEPAGE=65001%>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<HTML xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
<TITLE>DOM-TEST</TITLE>
</HEAD>
<BODY>

<% Session.CodePage = 65001 %>

<%
 '各種パス
 Const sDefFile = "D:\hensyu\TanConTest\Def.xml"'読み出し元
 Const sTraFile = "D:\hensyu\TanConTest\Tra.xml"'作成用
 'XPath(必要最小限を記載)
    Const sXPath = "DATA/MOJI"
  
 dim sData
  
 'フォームのデータを参照
 sData = Request.Form("t_moji")

 'DOM宣言
 Dim xDoc
 Set xDoc = Server.CreateObject("MSXML2.FreeThreadedDOMDocument.3.0") 
 xDoc.async = False
 xDoc.validateOnParse = False
 xDoc.load(sDefFile)
  
 'DOM編集
 xDoc.SelectSingleNode(sXPath).Text = sData


 'XML保存
 Const adTypeText = 2
 Const adSaveCreateOverWrite = 2
 With Server.CreateObject("ADODB.Stream")
  .Type = adTypeText
  .Charset = "UTF-16"
  .Open
  .WriteText xDoc.XML
  .SaveToFile sTraFile , adSaveCreateOverWrite
  .Close
 End With
  
  
 'DOM開放
 Set xDoc = Nothing

%>

編集 削除
魔界の仮面弁士  2008-04-04 17:02:51  No: 139454  IP: 192.*.*.*

> どこぞやのページ
具体的にはどこですか?

> UTF-8はRequest.Formが動作しないとありましたが
ウチで作っている ASP サイトの半数は、UTF-8 ベースですが、
そのような現象を経験した事は無いですね…。


> ASPファイルをUTF-8化したつもりで検証を行ったところ
その ASP ソースファイルは、[BOM付きのUTF-8] として保存しましたか?
それとも、[BOM無しのUTF-8] として保存しましたか?

私は普段、BOM 付きにして保存していますが、IIS のバージョンによっては、
BOM 無しで保存した方が良い場合があります。
http://support.microsoft.com/kb/301623/ja


> <%@Language="VBScript" CODEPAGE=65001%>
> <?xml version="1.0" encoding="UTF-8" standalone="no"?>

これは明らかにまずいでしょう……。

"<?xml" の前に、余計なデータ(改行文字)が含まれていますし、
そもそもこの文書は、どうみても XML の構文にはなっていませんよね。

もし、<?xml version="1.0"?> を宣言したいなら、たとえば下記のように
なりますが、今回は別に XHTML にしたわけでは無いのですよね?
であれば、そのような記述を使うべきではないかと。

=================
<% @ CodePage="65001" Language="VBScript" %><%Option Explicit%><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 
<html xml:lang="ja" lang="ja" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<link rel="stylesheet" type="text/css" charset="UTF-8" href="sample.css" />
<title>Sample</title>
以下略
=================


> ちなみにUTF-8の部分をUTF-16に変えて検証したところ
どことどこを UTF-16 に変えたのでしょうか?

UTF-16 なページを作れないわけではありませんが、IIS 自体は Codepage = 1200 を
サポートしないので、難易度が上がってしまうと思いますよ。
http://support.microsoft.com/kb/254313/ja


> 'フォームのデータを参照
> sData = Request.Form("t_moji")
DOM 云々の前に、ここの部分が化けてしまう問題を解決するのが先ですから、
まずは、sData の内容を確認できるようなコードを記述するべきかと。


> Set xDoc = Server.CreateObject("MSXML2.FreeThreadedDOMDocument.3.0")
何故、今更 MSXML3 を利用されているのでしょう? (^^;

> xDoc.load(sDefFile)
括弧が冗長です。
VBScript では、メソッドの呼び出しに括弧を伴いませんので、上記のコードは、
Call xDoc.load((sDefFile))
という意味で解釈される事になります。

編集 削除
魔界の仮面弁士  2008-04-04 17:08:23  No: 139455  IP: 192.*.*.*

あう。DOCTYPE をコピーし損ねました。m(_ _;)m

今回は(HXTMLではなく)HTMLなので、あまり関係は無いのですけれども、
一応訂正しておきます。


《誤》
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 

《正》
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

編集 削除
taktak  2008-04-04 19:41:44  No: 139456  IP: 192.*.*.*

魔界の仮面弁士様のサンプルを参考にすることで、入力画面で入力した文字[ED36]をXMLファイルに書きだすことができました。本当にありがとうございます。
>その ASP ソースファイルは、[BOM付きのUTF-8] として保存しましたか?
>それとも、[BOM無しのUTF-8] として保存しましたか?
ここが大きな原因だったようです。なにせ本当に文字コードにうとくて。
どのように勉強していくか課題です。
ちなみに魔界の仮面弁士様は、どのようなエディアを使ってますか。参考にさせて下さい。

> Set xDoc = Server.CreateObject("MSXML2.FreeThreadedDOMDocument.3.0")
>何故、今更 MSXML3 を利用されているのでしょう? (^^;
正直理由はありませんで、理解していないまま使ってました。参考までに
MSXML?について教えていただけませんでしょうか。

私の知識不足でご迷惑をかけましたが、本当に助かりました。

編集 削除
ナナシ  2008-04-04 21:35:59  No: 139457  IP: 192.*.*.*

解決したなら解決チェックを。
だらだら長くなるので追加質問はしないでください。

#聞く前に調べよう。

編集 削除
taktak  2008-04-04 21:48:29  No: 139458  IP: 192.*.*.*

>だらだら長くなるので追加質問はしないでください。
申し訳ございません。終了させていただきます。

編集 削除
魔界の仮面弁士  2008-04-08 11:15:18  No: 139459  IP: 192.*.*.*

》ナナシさん
> だらだら長くなるので追加質問はしないでください。
うーむ。追加質問という訳では無いのですけれども、私の方からの逆質問に、
まだ幾つか答えてもらっていないので、消化不良なんですよね。。。


》taktakさん
>>> どこぞやのページにUTF-8はRequest.Formが動作しないとありましたが、それが原因でしょうか。
>> 具体的にはどこですか?
この件ですが、その後、ページの所在を思い出せましたでしょうか?
是非、そのURL を教えてください。

taktak さんがページの内容を誤読されたのか、そもそもそのページの内容が間違っているのか、
あるいは、私が知らない落とし穴があったのかなど、きちんと把握しておきたいので。


>> その ASP ソースファイルは、[BOM付きのUTF-8] として保存しましたか?
>> それとも、[BOM無しのUTF-8] として保存しましたか?
> ここが大きな原因だったようです。
結局、どちらで保存されたのでしょうか? それとも、どちらでも無かったのでしょうか?


> どのようなエディアを使ってますか。参考にさせて下さい。
エディア…。もしかして、Editor の事でしょうか。
http://response.jp/issue/2007/1012/article100369_1.html

何を記述するのか(アイディアメモ、Webアプリコード、スクリプト、メール等々)により、
その時々で使うソフトウェアは異なりますが、たとえば
・メモ帳 (Win2000以降)
・Visual Studio 2008
・Visual InterDev
・OneNote
・Word Mobile
・秀丸
・oSqlEdit
・Becky! 2.0
などを利用する事が多いです。


>> Set xDoc = Server.CreateObject("MSXML2.FreeThreadedDOMDocument.3.0")
>> 何故、今更 MSXML3 を利用されているのでしょう? (^^;
> 正直理由はありませんで、理解していないまま使ってました。
クライアントサイドであれば、IE6 にも付属している MSXML3 で済ますのも手ですが、
サーバサイドであるならば、できるだけ上位のバージョンを使った方が良いかと思います。

ただし MSXML4/SP2 には、下記「2004年 06月 14日 16時 10分 17秒」の記事の
http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list108.shtml
問題もありますので、できれば、それより後のバージョンの方が良いかも知れません。

なお、それぞれは Side-by-side で共存インストールされますので、万一、特定バージョンでの
動作に問題があったとしても、別バージョンを CreateObject して使う事が可能です。
(Service Pack の Side-by-side インストールはできませんけれども)


> 参考までにMSXML?について教えていただけませんでしょうか。
質問内容は具体的にお願いします。m(_ _)m
MSXML の何について教えれば良いでしょうか?

バージョン一覧についてでしょうか? であれば、このあたりを見てください。
http://support.microsoft.com/kb/269238/ja
http://www.interq.or.jp/japan/koi_san/trash/2004/msxml.htm
http://support.microsoft.com/kb/278636/ja

それとも、ダウンロード先でしょうか? ならば、Download Center 等から
入手できるものと、Office 等に付属の(再頒布不可な)バージョンなどがあります。

あるいは、パフォーマンスの点においてでしょうか?
もしそうなら、かなり古い資料ですが、このような物があります。
http://www.microsoft.com/japan/msdn/columns/xml/xml02212000.aspx
http://www.microsoft.com/japan/msdn/columns/xml/xml03202000.aspx

編集 削除