将XML转换为IEnumerable<T>

7

有没有一种方法可以将给定的XML文件转换(最好使用C#泛型)为我的具体类 T 的具体可枚举列表

例如,我可能有一个像这样的XML文件

<fruits>
    <fruit>
        <id>1</id>
        <name>apple</name>
    </fruit>
    <fruit>
        <id>2</id>
        <name>orange</name>
    </fruit>
</fruits>

我希望看到一个水果对象列表

其中包含以下属性:

public class Fruit : IFruit
{
    public string name;
    public int id;
}

我假设如果我要使用泛型,我需要某种映射,因为我希望这个工作最好适用于IFruit接口(不确定是否可能)。
提前致谢。
3个回答

10

考虑以下类型:

public interface IFruit
{
    String name { get; set; }
    Int32 id { get; set; }
}

public class Fruit : IFruit
{
    public String name { get; set; }
    public Int32 id { get; set; }
}

我认为你可以像这样做:

我认为您可以这样做:

    static IEnumerable<T> GetSomeFruit<T>(String xml)
        where T : IFruit, new()
    {
        return XElement.Parse(xml)
            .Elements("fruit")
            .Select(f => new T {
                name = f.Element("name").Value,
                id = Int32.Parse(f.Element("id").Value)
            });
    }

您可以这样调用:
IEnumerable<Fruit> fruit = GetSomeFruit<Fruit>(yourXml);

我喜欢这个解决方案,而且它实际上也支持启用XML序列化。我唯一的评论是,.NET惯例通常要求公共字段(或更现实地说,公共属性)以大写字母开头,但那是Harrison的决定,而不是你的。 - Steven Sudit
很好。为了更进一步,我想象会有每种水果的子类,用于通用方法返回匹配类型的水果节点,例如如果T=Orange,则返回那些名称为Orange的水果。该方法可以比较typeof(T).Name与xml中水果的名称并排除其他水果...只是我的建议。 - Abhijeet Patel

3

如果你喜欢使用序列化的方式,这里有一种方法:

using System;
using System.IO;
using System.Xml.Serialization;

public static class Test
{
    public static void Main(string[] args)
    {
        var fs = new FileStream("fruits.xml", FileMode.Open);
        var x = new XmlSerializer(typeof(Fruits));
        var fruits = (Fruits) x.Deserialize(fs);
        Console.WriteLine("{0} count: {1}", fruits.GetType().Name, fruits.fruits.Length);
        foreach(var fruit in fruits.fruits)
            Console.WriteLine("id: {0}, name: {1}", fruit.id, fruit.name);
    }
}

[XmlRoot("fruits")]
public class Fruits
{
    [XmlElement(ElementName="fruit")]
    public Fruit[] fruits;
}

public class Fruit
{
    public string name;
    public int id;
}

感谢您提供示例代码来完善我的即兴建议。 - Steven Sudit
谢谢,这让我更清楚了。由于我没有在 XML 中进行过太多序列化,所以我很难理解泛型部分 - 真是太好了! - Mark H

0

我不确定我完全理解你的情况,但是一种方法是定义一个数据传输类并使其在XML中可序列化。然后,您可以将XML反序列化为对象数组。

编辑

我不会删除这个,但我认为Andrew Hare发布的更接近您想要的,并且我已经支持他。


@Steven - 抱歉,我删除了我的帖子,重新思考了问题,然后在编辑后取消了删除我的答案。对于造成的混乱感到抱歉! - Andrew Hare
没问题。我会删除重复的代码以避免混淆。 - Steven Sudit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接