4

オブジェクトの xml をXmlDocumentHTTP クライアントに送信したいのですが、提案されResponseた解決策が、使用するように設定されているエンコーディングを尊重しない可能性があることを懸念しています。

public void ProcessRequest(HttpContext context)
{
   XmlDocument doc = GetXmlToShow(context);

   context.Response.ContentType = "text/xml";
   context.Response.ContentEncoding = System.Text.Encoding.UTF8;
   context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
   context.Response.Cache.SetAllowResponseInBrowserHistory(true);

   doc.Save(context.Response.OutputStream);

}

エンコーディングを別のもの、たとえばUnicodeに変更した場合:

public void ProcessRequest(HttpContext context)
{
   XmlDocument doc = GetXmlToShow(context);

   context.Response.ContentType = "text/xml";
   context.Response.ContentEncoding = System.Text.Encoding.Unicode;
   context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
   context.Response.Cache.SetAllowResponseInBrowserHistory(true);

   doc.Save(context.Response.OutputStream);
}

Response.OutputStreamオンザフライで書き込まれているバイナリ データを変換し、Unicode にしますか?

それともResponse.ContentEncoding単なる有益ですか?

ContentEncoding が単なる参考情報である場合、次のテキスト文字列はどのコンテンツ エンコーディングで返されるでしょうか?

context.Response.ContentEncoding = System.Text.Encoding.Unicode;
context.Response.Write("Hello World");

context.Response.ContentEncoding = System.Text.Encoding.UTF8;
context.Response.Write("Hello World");

context.Response.ContentEncoding = System.Text.Encoding.UTF16;
context.Response.Write("Hello World");

context.Response.ContentEncoding = System.Text.Encoding.ASCII;
context.Response.Write("Hello World");

context.Response.ContentEncoding = System.Text.Encoding.BigEndianUnicode;
context.Response.Write("Hello World");
4

2 に答える 2

14

見つけた。

答えはノーです。XmlDocument は、書き込み先の応答ストリームの ContentEncoding を尊重しません。


更新:それを行う適切な方法

  1. Response.OutputおよびNOT を使用しResponse.OutputStreamます。

    どちらもストリームですOutputが、TextWriter.

    XmlDocumentが自身を に保存するとき、TextWriterで指定されたエンコーディングを使用しますTextWriterXmlDocumentは、xml 宣言ノードを自動的に変更します。つまり、次のようになります。

    <?xml version="1.0" encoding="ISO-8859-1"?>

    のエンコーディング設定で使用されるエンコーディングと一致させResponse.Outputます。

  2. Response.Output TextWriterエンコーディング設定は Response.ContentEncoding値から取得されます。

  3. を使用するdoc.Save、または使用しない Response.Write(doc.ToString())Response.Write(doc.InnerXml)

    xml を文字列に保存したり、xml を文字列に詰め込んだりする必要はありませresponse.Write

    • 指定されたエンコーディングに従っていません
    • メモリを無駄にします

要約すると、次のように保存されますTextWriter: XML 宣言ノード、XML コンテンツ、および HTML 応答のコンテンツ エンコーディングがすべて一致します。

サンプルコード:

public class Handler : IHttpHandler, System.Web.SessionState.IRequiresSessionState 
{
    //Note: We add IRequiesSessionState so that we'll have access to context.Session object
    //Otherwise it will be null


    public void ProcessRequest(HttpContext context)
    {
        XmlDocument doc = GetXmlToShow(context); //GetXmlToShow will look for parameters from the context

        if (doc != null)
        {
            context.Response.ContentType = "text/xml"; //must be 'text/xml'
            context.Response.ContentEncoding = System.Text.Encoding.UTF8; //we'd like utf-8
            doc.Save(context.Response.Output); //doc save itself to the textwriter, using the encoding of the text-writer (which comes from response.contentEncoding)
        }

        #region Notes
        /*
         * 1. Use Response.Output, and NOT Response.OutputStream.
         *    Both are streams, but Output is a TextWriter.
         *    When an XmlDocument saves itself to a TextWriter, it will use the encoding
         *    specified by the TextWriter. The XmlDocument will automatically change any
         *    xml declaration node, i.e.:
         *       <?xml version="1.0" encoding="ISO-8859-1"?>
         *    to match the encoding used by the Response.Output's encoding setting
         * 2. The Response.Output TextWriter's encoding settings comes from the 
         *    Response.ContentEncoding value.
         * 3. Use doc.Save, not Response.Write(doc.ToString()) or Response.Write(doc.InnerXml)
         * 3. You DON'T want to Save the xml to a string, or stuff the xml into a string
         *    and response.Write that, because that
         *     - doesn't follow the encoding specified
         *     - wastes memory
         * 
         * To sum up: by Saving to a TextWriter: the XML Declaration node, the XML contents,
         * and the HTML Response content-encoding will all match.
         */
        #endregion Notes
    }

    public bool IsReusable { get { return false; } }
}

ストリームに保存するときに XmlDocument が使用するエンコーディングは、xml 宣言ノードで指定されたエンコーディングによって異なります。例えば:

     <?xml version="1.0" encoding="UTF-8"?>

xml 宣言で「UTF-8」エンコーディングが指定されている場合、Save(stream) はUTF-8エンコーディングを使用します。

エンコーディングが指定されていない場合、例えば:

<?xml version="1.0"?>

または xml 宣言ノードが完全に省略されている場合、XmlDocument はデフォルトでUTF-8 Unicode エンコーディングになります。(参考

encoding 属性が含まれていない場合、ドキュメントが書き込まれるか保存されるときに UTF-8 エンコーディングが想定されます。

xml 宣言でも使用できるいくつかの一般的なエンコーディング文字列は次のとおりです。

  • UTF-8
  • UTF-16
  • ISO-10646-UCS-2
  • ISO-10646-UCS-4
  • ISO-8859-1
  • ISO-8859-2
  • ISO-8859-3
  • ISO-8859-4
  • ISO-8859-5
  • ISO-8859-6
  • ISO-8859-7
  • ISO-8859-8
  • ISO-8859-9
  • ISO-2022-JP
  • Shift_JIS
  • EUC-JP

: encoding 属性は大文字と小文字を区別しません。

ほとんどの XML 属性とは異なり、エンコーディング属性値では大文字と小文字が区別されません。これは、エンコーディング文字名が ISO および Internet Assigned Numbers Authority (IANA) 標準に従っているためです。

文字列またはファイルから XML をロードし、xml 宣言ノードが含まれていない場合は、次を使用して XmlDocument に手動で追加できます。

// Create an XML declaration. 
XmlDeclaration xmldecl;
xmldecl = doc.CreateXmlDeclaration("1.0", null, null);
xmldecl.Encoding="UTF-8";

// Add the new node to the document.
XmlElement root = doc.DocumentElement;
doc.InsertBefore(xmldecl, root);

XmlDocument に xml 宣言がない場合、または xml 宣言に encoding 属性がない場合、保存されたドキュメントにもそれはありません。

注: XmlDocument が TextWriter に保存されている場合、使用されるエンコーディングは TextWriter オブジェクトから取得されます。さらに、xml 宣言ノードのエンコーディング属性 (存在する場合) は、コンテンツが TextWriter に書き込まれるときに、TextWriter のエンコーディングに置き換えられます。(参考

TextWriter のエンコーディングによって、書き出されるエンコーディングが決まります (XmlDeclaration ノードのエンコーディングは、TextWriter のエンコーディングに置き換えられます)。TextWriter でエンコーディングが指定されていない場合、XmlDocument はエンコーディング属性なしで保存されます。

文字列に保存する場合、使用されるエンコーディングは、xml 宣言ノードのエンコーディング属性 (存在する場合) によって決定されます。


私の具体的な例では、ASP.NET を介して Http クライアントに書き戻しています。Response.Encoding タイプを適切な値に設定したいのですが、XML 自体に含まれるものと一致させる必要があります。

これを行う適切な方法は、xml を Response.OutputStream ではなく Response.Output に保存することです。Response.Output は TextWriter であり、その Encoding 値は Response.Encoding に設定した値に従います。

言い換えると:

context.Response.ContentEncoding = System.Text.Encoding.ASCII;
doc.Save(context.Response.Output);

xml の結果:

<?xml version="1.0" encoding="us-ascii" ?> 
<foo>Hello, world!</foo>

その間:

context.Response.ContentEncoding = System.Text.Encoding.UTF8;
doc.Save(context.Response.Output);

xml の結果:

<?xml version="1.0" encoding="utf-8" ?> 
<foo>Hello, world!</foo>

context.Response.ContentEncoding = System.Text.Encoding.Unicode;
doc.Save(context.Response.Output);

xml の結果:

<?xml version="1.0" encoding="utf-16" ?> 
<foo>Hello, world!</foo>
于 2009-02-13T18:38:43.197 に答える
-1

Google からの最初の 2 つのリンク

方法: ASP.NET Web ページ グローバリゼーションのエンコーディングを選択する: http://msdn.microsoft.com/en-us/library/hy4kkhe0.aspx

グローバリゼーション要素 (ASP.NET 設定スキーマ): http://msdn.microsoft.com/en-us/library/hy4kkhe0.aspx

于 2009-02-13T18:05:17.787 に答える