XML反序列化泛型方法(XML deserialization generic method)

2019-07-18 20:32发布

我有下一个XML文件:

<Root>
    <Document>      
        <Id>d639a54f-baca-11e1-8067-001fd09b1dfd</Id>
        <Balance>-24145</Balance>
    </Document>
    <Document>      
        <Id>e3b3b4cd-bb8e-11e1-8067-001fd09b1dfd</Id>
        <Balance>0.28</Balance> 
    </Document>
</Root>

我把它反序列化到这个类:

[XmlRoot("Root", IsNullable = false)]
public class DocBalanceCollection
{
    [XmlElement("Document")]
    public List<DocBalanceItem> DocsBalanceItems = new List<DocBalanceItem>();
}

其中DocBalanceItem是:

public class DocBalanceItem
{
    [XmlElement("Id")]
    public Guid DocId { get; set; }

    [XmlElement("Balance")]
    public decimal? BalanceAmount { get; set; }
}

这里是我的反序列化方法:

public DocBalanceCollection DeserializeDocBalances(string filePath)
{
    var docBalanceCollection = new DocBalanceCollection();

    if (File.Exists(filePath))
    {
        var serializer = new XmlSerializer(docBalanceCollection.GetType());
        TextReader reader = new StreamReader(filePath);
        docBalanceCollection = (DocBalanceCollection)serializer.Deserialize(reader);
        reader.Close();
    }

    return docBalanceCollection;
}

所有工作正常,但我有很多的XML文件。 除了写作Item类我必须写ItemCollection类为他们每个人。 同时,我必须执行DeserializeItems每种方法。

我可以反序列化,而无需创建我的XML文件ItemCollection类? 我可以写一个通用的方法来反序列化所有的人?

我想到的唯一的解决办法 - 将界面为所有这些类。 有任何想法吗?

Answer 1:

你可以反序列化泛型List<T>只是XmlSerializer的罚款。 但是,首先你需要将添加XmlType属性您DocBalanceItem所以它知道列表元素的命名方式。

[XmlType("Document")]
public class DocBalanceItem
{
    [XmlElement("Id")]
    public Guid DocId { get; set; }

    [XmlElement("Balance")]
    public decimal? BalanceAmount { get; set; }
}

然后修改您DeserializeDocBalances()方法返回一个List<T>并通过串行一个XmlRootAttribute实例来指示它寻找Root作为根元素:

public List<T> DeserializeList<T>(string filePath)
{
    var itemList = new List<T>();

    if (File.Exists(filePath))
    {
        var serializer = new XmlSerializer(typeof(List<T>), new XmlRootAttribute("Root"));
        TextReader reader = new StreamReader(filePath);
        itemList = (List<T>)serializer.Deserialize(reader);
        reader.Close();
    }

    return itemList;
}

那么你应该能够做到

var list = DeserializeList<DocBalanceItem>("somefile.xml");

由于该方法现在返回一个泛型List<T>您不再需要为每个类型创建自定义集合。

PS - 我在本地与所提供的文件进行测试这个解决方案,它的工作。



Answer 2:

任何串接的目的可以通过以下的方法进行反序列化。

public static T genericDeserializeSingleObjFromXML<T>(T value, string XmalfileStorageFullPath)
        {             
            T Tvalue = default(T);
            try
            {
                XmlSerializer deserializer = new XmlSerializer(typeof(T));
                TextReader textReader = new StreamReader(XmalfileStorageFullPath);
                Tvalue = (T)deserializer.Deserialize(textReader);
                textReader.Close();

            }
            catch (Exception ex)
            {                   
            System.Windows.Forms.MessageBox.Show("serialization Error : " + ex.Message);                
            }
            return Tvalue;
        }

为了使用这种方法,你应该已经序列化XML文件的对象。 调用的方法是:

XmlSerialization.genericDeserializeSingleObjFromXML(new ObjectName(), "full path of the XML file");


文章来源: XML deserialization generic method