簡體   English   中英

.NET XML序列化

[英].NET XML serialization

我想將混合數據序列化和反序列化為XML。 經過一些搜索,我發現有兩種方法可以執行此操作: System.Runtime.Serialization.Formatters.Soap.SoapFormatterSystem.Xml.Serialization.XmlSerializer 但是,沒有一個符合我的要求,因為:

  • SoapFormatter不支持泛型類型的序列化
  • XmlSerializer拒絕序列化實現IDictionary的類型,更不用說它比“普通”序列化更不易使用(例如, 參見此SO問題

我想知道是否存在沒有這些限制的實現? 我找到了嘗試(例如,在相關的SO問題中建議的CustomXmlSerializerYAXLib ),但它們似乎也不起作用。

我當時正在考慮自己編寫這樣的序列化器(盡管這顯然不是一件容易的事),但是后來我發現自己受到了CLR的限制,因為我無法創建不會具有無參數構造函數的類型的對象實例。 ,即使我使用反射。 我記得在某處讀過 System.Runtime.Serialization中的 實現時 ,雖然不確定,但是 在反序列化對象時會以某種方式繞過常規的對象創建機制 關於如何做到這一點的任何暗示?
(請參見編輯#3)

有人可以為此指出正確的方向嗎?

編輯 :我正在使用.NET 3.5 SP1。

編輯#2 :為了清楚起見,我想要一個盡可能類似於使用BinaryFormatter的解決方案,這意味着它應該需要最少的額外代碼和注釋。

編輯#3 :通過一些額外的Google搜索,我發現了一個名為System.Runtime.Serialization.FormatterServices.GetUninitializedObject的.NET類,該類實際上可以返回指定類型的“清零”對象,這在反序列化方面很有幫助(如果我要實現的話)我自己)。 我仍然想找到一個現有的解決方案。

Ive使用datacontractserializer類取得了巨大的成功。 這里

這是一篇比較串行器鏈接的不錯的文章

您使用哪個版本的.NET Framework? 如果您使用的是.NET 3.0或更高版本,則您可能對DataContractSerializerNetDataContractSerializer感到幸運。 兩者都可以序列化為XML,但工作方式與XmlSerializer完全不同。

根據您的.NET版本和數據的復雜性,使用LINQ to XML進行序列化可能會很幸運:

internal class Inner
{
    public int Number { get; set; }
    public string NotNumber { get; set; }
}

internal class Outer
{
    public int ID { get; set; }
    public Dictionary<string, Inner> Dict { get; set; }
}

internal class Program
{
    private static void Main()
    {
        var data = new Outer
                       {
                           ID = 1,
                           Dict =
                               new Dictionary<string, Inner>
                                   {
                                       {
                                           "ABC",
                                           new Inner
                                               {
                                                   Number = 1,
                                                   NotNumber = "ABC1"
                                               }
                                           },
                                       {
                                           "DEF",
                                           new Inner
                                               {
                                                   Number = 2,
                                                   NotNumber = "DEF2"
                                               }
                                           }
                                   }
                       };

        var serialized =
            new XDocument(new XElement("Outer",
                                       new XAttribute("id", data.ID),
                                       new XElement("Dict",
                                                    from i in data.Dict
                                                    select
                                                        new XElement(
                                                        "Entry",
                                                        new XAttribute(
                                                            "key", i.Key),
                                                        new XAttribute(
                                                            "number",
                                                            i.Value.Number),
                                                        new XAttribute(
                                                            "notNumber",
                                                            i.Value.
                                                                NotNumber)))));

        Console.WriteLine(serialized);
        Console.Write("ENTER to finish: ");
        Console.ReadLine();
    }
}

結果:

<Outer id="1">
  <Dict>
    <Entry key="ABC" number="1" notNumber="ABC1" />
    <Entry key="DEF" number="2" notNumber="DEF2" />
  </Dict>
</Outer>

反序列化:

private static Outer Deserialize(XDocument serialized)
{
    if (serialized.Root == null)
    {
        return null;
    }

    var outerElement = serialized.Root.Element("Outer");
    if (outerElement == null)
    {
        return null;
    }

    return new Outer
               {
                   ID =
                       int.Parse(
                           outerElement.Attribute("id").Value),
                   Dict =
                       outerElement.Element("Dict").
                           Elements("Entry").ToDictionary(
                               k => k.Attribute("key").Value,
                               v => new Inner
                                    {
                                       Number = Convert.ToInt32(v.Attribute("number").Value),
                                       NotNumber = v.Attribute("notNumber").Value
                                    })
               };
}

實現自定義XML序列化還不錯。 您可以在默認情況下普通XmlSerializer無法支持的類中實現IXmlSerializable

這篇CodeProject文章IXmlSerializable了很好的解釋,並且該博客文章或多或少提供了相同的東西。

我建議使用DataContractJsonSerializer,它可以縮短輸出並更好地處理字典。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM