Indy 10 の最新バージョンを使用している場合、オーバーロードされたバージョンの Indy 10 は、データを Unicode にデコードしTIdHTTP.Post()ますが、String デコードに使用される実際の文字セットは、HTTPContent-Type応答ヘッダーが指定するメディア タイプによって異なります。
メディア タイプがapplication/xml、application/xml-external-parsed-entity、application/xml-dtd、またはtext/...タイプではなく、 で終わる場合、XML のプロローグの属性で+xml指定された文字セットが使用されます。encoding文字セットが指定されていない場合は、UTF-8 が使用されます。
それ以外の場合、Content-Type応答ヘッダーで文字セットが指定されている場合は、それが使用されます。
それ以外の場合、メディア タイプがtext/...タイプの場合:
を。メディア タイプがtext/xml、text/xml-external-parsed-entity、または で終わる場合は+xml、us-asciiが使用されます。
b. それ以外の場合ISO-8859-1は使用されます。
それ以外の場合は、Indy のデフォルトのエンコーディング (デフォルトでは ASCII) が使用されます。
実際の HTTPContent-Typeヘッダーを確認しないと、状況がどのような状況に陥るかを判断するのは困難です。ISO-8859-1または同様の文字セットが使用されている場合、そのまま返されるUTF-8バイト値を説明する#2または#3bのいずれかに該当するようです。
UTF8ToString()入力としてエンコードされた UTF-8が必要ですが、代わりにRawByteStringエンコードされた UTF-16 を渡しています。UnicodeStringRTL は、変換にデフォルトの Ansi 文字セットを使用して、UTF16->Ansi 変換を実行します。このような変換ではデータが失われる可能性があるため、コンパイラの警告が表示されるのはそのためです。
XML は実際にはバイナリ データ形式であり、文字セット エンコーディングが適用されます。XML パーサーは、XML のエンコーディングが何であるかを認識し、それに応じて生のエンコードされたバイトを解析できる必要があります。encodingそのため、XML はXML プロローグに明示的な属性を持っています。ただし、TIdHTTPXML を としてダウンロードすると、String自動的に Unicode にデコードされますが、それに応じて XML のプロローグはまだ更新されません。
String本当の解決策は、最初から XML を としてダウンロードしないことです。XMLパーサーが元のバイト、元の文字セット宣言などにアクセスできるように、TStream代わりに(TMemoryStreamよりも良い選択です)としてダウンロードします。たとえば、をメソッドに渡すことができます。TStringStreamTStreamTXMLDocument.LoadFromStream()