|
やじゅ様 および なちゃ様
ご返答ありがとうございます。
質問時に掲載しましたコードは同じ状況が発生する最低限のコードでした。
実際にはEncodingを指定し、XmlWriterSettingsのEncodingと
GetString()に用いるEncodingを同じものにしていました。
>ところで、?とは何で見たときに?なんでしょう?
確認用出力は、Console.WriteLine()を使いました。
(が、問題はここにもありました!)
▼----------【Encodingを指定したつもりのコードここから】----------▼
Encoding utf8 = Encoding.UTF8;//= new UTF8Encoding();
using(MemoryStream stream = new MemoryStream()){
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = utf8;
using(XmlWriter writer = XmlWriter.Create(stream, settings)){
//中略
}
Console.WriteLine(utf8.GetString(stream.ToArray()));
}
▲----------【Encodingを指定したつもりのコードここまで】----------▲
BOMの可能性については上記のコードで解決したつもりでしたが・・・
実は違いました。
----------
■追試
----------
今まではVisual Studioだけでデバッグしていましたが、
文字エンコードが絡むことなので、
「信頼のおける」別のソフトを使って追試を行うことにしました。
秀丸エディタでUTF8 BOM付きのテキストを作成し、
バイナリエディタBzで作成したテキストを開いて、
バイナリ列をbyte[]に直接書き写したものをEncoding.UTF8でGetString()すると
先頭に「?」が挿入される現象が再現されます。
→やはり問題はBOMのようです
次に、日本語とアラビア語が混在したstringのインスタンスを持たせ、
EncodingをEncoding.Unicode(UTF16)に変更。
それを上記のコードでSerialize()→GetString()を試すと文字化けしました!
→XmlWriteSettings.Encodingが無視され、常にUTF-8でエンコードされているようです
さらに、Encoding.UTF8でも、System.Diagnostics.Debug.WriteLine()だと、
「?」が挿入されないことにも気づきました。
→あれ?
・・・という状況説明だけでは何も伝わらないと思うので、
同じ問題に遭遇した人(いるのか?)のためにまとめて起きたいと思います。
----------
■まとめ
----------
この問題の原因には、下記の2つの仕様が関わっているようです。
1. XmlWriterSetting.Encodingは、
XMLのプリアンブルに含まれるencoding属性を書き換えるだけで、
StreamにどのEncodingで書き込むかというのを制御しないという仕様。
Encodingを指定するためには、StreamWriterのインスタンスを渡す必要がある。
▼----------【正常に動作するコードここから】----------▼
Encoding utf8 = Encoding.UTF8;//= new UTF8Encoding();
using(MemoryStream stream = new MemoryStream()){
using(StreamWriter wrapper = new StreamWriter(stream, utf8)){
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = utf8;
using(XmlWriter writer = XmlWriter.Create(wrapper, settings)){
//中略
}
Console.WriteLine(utf8.GetString(stream.ToArray()));
}
}
▲----------【正常に動作するコードここまで】----------▲
2. Console.WriteLine()は日本語版WindowsではCP932への変換を経てVisual Studioに伝わるため、
Unicode文字列(BOMも)をConsole.WriteLine()で出力すると正常に表示されないという仕様。
参考:http://oshiete1.goo.ne.jp/qa684358.html
ということが分かりました。
お二方のご指摘通り問題はBOMでした。
Encodingが絡む場合はかなり注意してコードを組まないといけないんですね・・・
どうもありがとうございました。
|