0

私のデータ エンティティにはディクショナリが含まれていますが、XmlSerializer はそのままではそれらをサポートしていません。そこで、DataContractSerializer を使用することにしました。問題は、必要に応じて動作させることができないことです。

私は次のコードから始めました:

public static string SerializeObject<T>(T serialisable)
{
    var serializer = new DataContractSerializer(serialisable.GetType());
    using (var writer = new StringWriter())
    using (var stm = new XmlTextWriter(writer))
    {
        serializer.WriteObject(stm, serialisable);
        return writer.ToString();
    }
}

"\r\n" を文字列に入れると、XML エンティティにシリアル化されないことに気付くまでは、問題なく動作しているように見えました。XmlSerializer の経験から、NewLineHandling = NewLineHandling.Entitize を使用して XmlWriterSettings を設定できることがわかりました。そこで、コードを次のように変換しました。

public static string SerializeObject<T>(T serialisable)
{
    var serializer = new DataContractSerializer(serialisable.GetType());
    using (var writer = new StringWriter())
    {
        using (var stm = XmlWriter.Create(writer,
            new XmlWriterSettings()
            {
                NewLineHandling = NewLineHandling.Entitize
            }))
        {
            serializer.WriteObject(stm, serialisable);
            return writer.ToString();
        }
    }
}

問題は、空の文字列を取得することです。例外はなく、何もありません - 空の文字列だけです。stm 変数は XmlWellFormedWriter を保持します。たぶん、DataContractSerializer でサポートされていないのでしょうか?

次に、次のように XmlTextWriter を強制しようとしました。

public static string SerializeObject<T>(T serialisable)
{
    var serializer = new DataContractSerializer(serialisable.GetType());
    using (var writer = new StringWriter())
    using (var stm = XmlWriter.Create(new XmlTextWriter(writer),
        new XmlWriterSettings()
        {
            NewLineHandling = NewLineHandling.Entitize
        }))
    {
        serializer.WriteObject(stm, serialisable);
        return writer.ToString();
    }
}

そして、これで最初の場所に戻ります。XML 文字列が返されますが、"\r\n" 文字列はエンティティに変換されません。

改行をエンティティ化し、XML を文字列として返すように DataContractSerializer を作成するにはどうすればよいですか?

4

2 に答える 2

2

これはかなり古いスレッドであることは知っていますが、答えを探して偶然見つけたので、見つけたものに答えることにしました。

\n がエンティティ化されていない理由は、それらがテキスト ノード値にあるためです。シリアライザは、\n 文字が属性内にある場合のみ実体化します。

これは、NewLineHandling の各値で発生することがわかったことです。

テキスト ノード

NewLineHandling.Replace (Default) 
\r \n \r\n all go to \r\n
\t remains as \t

NewLineHandling.Entitize
\r\n goes to &#D;
\n remains as \n
\r goes to &#D;
\t remains as \t

NewLineHandling.None
\r remains \r
\r\n remains \n
\r\n remains \r\n
\t remains as \t

属性

NewLineHandling.Replace (Default) 
\r\n goes to &#D;&#A;
\n goes to &#A;
\r goes to &#D;
\t remains &#9;

NewLineHandling.Entitize
\r\n goes to &#D;&#A;
\n goes to &#A;
\r goes to &#D;
\t remains &#9;

NewLineHandling.None
\r remains \r
\r\n remains as \n
\r\n remains as \r\n
\t remains as \t
于 2014-04-01T22:56:01.920 に答える
0

XmlWriter.Createで作成すると、閉じるまでフラッシュしないため、StringWriterは空です。奇妙なことに、新しい XmlTextWriter で作成すると、どういうわけかその内容が StringWriter にフラッシュされるため、最初のメソッドは問題なく機能しました。

今回は、1 行のコードを再配置する必要がありました。

    public static string SerializeObject<T>(T serialisable)
    {
        var serializer = new DataContractSerializer(serialisable.GetType());
        using (var writer = new StringWriter())
        {
            using (var stm = XmlWriter.Create(writer,
                new XmlWriterSettings()
                {
                    NewLineHandling = NewLineHandling.Entitize,
                    Encoding = UTF8Encoding.UTF8
                }))
            {
                serializer.WriteObject(stm, serialisable);
                // <- previously writer.ToString() was here and I got an empty string
            }     

            return writer.ToString();
        }
    }

現在、「\r」文字は として正しくエンコードされています&#xD;が、「\n」はそうではありません。また、エンコーディングは UTF8 に設定していますが、まだ utf-16 です。それはまた別の問題だと思います。

于 2013-01-30T13:09:23.680 に答える