0

私はこれについて少し頭を悩ませてきました。それは簡単な解決策のように思えますが、私はインターネットを検索してかなりのことを試しました。

xml にシリアル化してから逆シリアル化する必要がある文字列リストを含む複雑なオブジェクトがあります。

シリアル化コードは長い間アプリケーションの一部であり、無数の他のシナリオで機能しますが、ここでの問題は、文字列リスト内の要素の 1 つが単なる改行文字 (つまり "\n") であることです。

私の理解では、私の調査に基づいて、期待どおりにシリアル化されていますが (以下を参照)、逆シリアル化の後、要素には "\n" ではなく空の文字列 (つまり "") が含まれています。

これがコードです...

public DoStuff(ItemTypeObj item)
{
    string myItem = XmlSerialize<ItemType>(item);
    ItemTypeObj myNewItemTypeObj = XmlDeserialize<CustomItem>(myItem)
}

public static string XmlSerialize<T>(T objectToSerialize)
{
    string ret = string.Empty;

    XmlSerializer s = new XmlSerializer(typeof(T));
    using (MemoryStream ms = new MemoryStream())
    {
        s.Serialize(ms, objectToSerialize);
        ms.Position = 0;
        using (StreamReader sr = new StreamReader(ms))
        {
            sRet = sr.ReadToEnd();
        }
    }
    return ret;
}

public static T XmlDeserialize<T>(string serializedObject)
{
    T retVal = default(T);
    byte[] ba = ASCIIEncoding.UTF8.GetBytes(serializedObject);
    using (MemoryStream ms = new MemoryStream(ba))
    {
        XmlSerializer s = new XmlSerializer(typeof(T));

        retVal = (T)s.Deserialize(ms);               
    }
    return retVal;
}

送信されたデータを理解するために、ItemTypeObj は文字列 List を含むオブジェクトです。文字列リストは可変長にすることができますが、サンプル データは次のようになります...

[0] = "Zero element text \n"
[1] = "[element1]"
[2] = "\n"
[3] = "[element3]"
[4] = "\n"
[5] = "[element5]"

シリアル化すると、次のようになります (これは私には正しいようです)。

  <Text>
    <string>Zero element text
</string>
    <string>[element1]</string>
    <string>
</string>
    <string>[element3]</string>
    <string>
</string>
    <string>[element5]</string>
 <Text>

私が読んだことから、改行は上記のxmlで期待どおりに表されます。問題は、文字列リストが次のように逆シリアル化された後です。

[0] = "Zero element text \n"
[1] = "[element1]"
[2] = ""
[3] = "[element3]"
[4] = ""
[5] = "[element5]"

テキストも含む要素 ([0] など) の改行文字のみが残ります。他の 2 つは空の文字列に置き換えられます。これらの要素にテキストを追加すると、新しい行が保持されます。

逆シリアル化のバイト配列を見ると、シリアル化された文字列の "\n" があった場所の配列要素が 10 (別名 LF、改行) に変わります。その後、デシリアライズで "\n" に変換されません。おそらく、それはあまりにも多くのことを求めています。

どんな洞察でも大歓迎です。ありがとう。

4

1 に答える 1

2

XmlReaderXmlWriterクラスまたはを使用する必要がありますDataContractSerializer

参照: XmlSerializer が文字列の NewLines を強制終了しないようにする方法は?

public static string XmlSerialize<T>(T objectToSerialize)
{
    XmlSerializer s = new XmlSerializer(typeof(T));

    var settings = new XmlWriterSettings
                       {
                           NewLineHandling = NewLineHandling.Entitize
                       };

    using(var stream = new StringWriter())
    using(var writer = XmlWriter.Create(stream, settings))
    {
        s.Serialize(writer, objectToSerialize);

        return stream.ToString();
    }
}

public static T XmlDeserialize<T>(string serializedObject)
{
    XmlSerializer s = new XmlSerializer(typeof(T));

    using(var stream = new StringReader(serializedObject))
    using(var reader = XmlReader.Create(stream))
    {
        return (T)s.Deserialize(reader);
    }
}

使用法:

public class Foo
{
    public string Bar { get; set; }
}

var foo = new Foo { Bar = "\n" };
var result = XmlSerialize(foo);

Console.WriteLine(result);

var newFoo = XmlDeserialize<Foo>(result);

Console.WriteLine(newFoo.Bar);
Debug.Assert(newFoo.Bar == "\n");
于 2013-06-25T14:51:03.187 に答える