2009-09-22 6 views
6

est-il un moyen de prendre un fichier XML donné et convertir (de préférence en utilisant Generics C#) dans une liste IEnumerable en béton de T où T est ma classe concrèteXML IEnumerable <T>

Ainsi, par exemple, je peux avoir un fichier XML comme

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

et je voudrais voir une liste de fruits Objets

où il a des propriétés comme

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

Je suppose que je besoin d'une sorte de cartographie si je devais utiliser les médicaments génériques, comme je voudrais que cela fonctionne pour idéalement l'interface IFruit (pas sûr si c'est possible)

Merci à l'avance

Répondre

9

Compte tenu des types suivants:

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; } 
} 

Je pense que vous pourriez faire quelque chose comme ceci:

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) 
      }); 
    } 

Ce qui vous appelleriez comme ceci:

IEnumerable<Fruit> fruit = GetSomeFruit<Fruit>(yourXml); 
+0

J'aime cette solution, et elle est en fait compatible avec l'activation de la sérialisation XML. Le seul commentaire que je ferais est que les conventions .NET exigent généralement que les champs publics (ou, plus vraisemblablement, les propriétés publiques) commencent par une majuscule, mais c'était la décision de Harrison, pas la vôtre. –

+0

Nice.Pour aller un peu plus loin, j'imagine qu'il y aurait des sous-classes pour chaque type de fruit pour une méthode générique telle que celle-ci pour retourner des nœuds de fruits d'un type correspondant, par exemple si T = Orange . La méthode pourrait comparer le typeof (T) .Name au nom du fruit du xml et exclure d'autres ... juste mes 2 cents –

+0

Vous êtes le génie, vous avez sauvé mon lot de travail – Moons

0

Je ne suis pas sûr de bien comprendre votre situation, mais une approche consiste à définir une classe de transfert de données et à la rendre sérialisable en XML. Ensuite, vous pouvez désérialiser le XML en un tableau d'objets.

modifier

Je ne vais pas supprimer, mais je pense que ce que Andrew Hare affiché est plus proche de ce que vous voulez, et je l'ai mis voté en faveur.

+0

@Steven - Désolé, j'ai supprimé mon post, repensé le problème, puis supprimé ma réponse après une modification. Désolé pour la confusion! –

+0

Pas de problème. Je vais supprimer le code en double pour éviter toute confusion. –

3

est ici un moyen pour le faire avec la sérialisation, si c'est votre truc:

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; 
} 
+0

Merci d'avoir mis ensemble l'échantillon de code à chair sur ma suggestion hors-la-manchette. –

+0

Merci cela a rendu beaucoup plus clair dans ma tête. J'ai eu du mal à trouver la partie générique car je n'ai pas fait beaucoup de sérialisation avec XML - parfait! – harrisonmeister

Questions connexes