2012-02-07 5 views
6

Carica un set di valori da un file XML e li inserisce in una classe per l'archiviazione. Sto cercando di capire come esportare i valori come elenco in modo da poterli inserire in una Listbox.Emissione di una classe di valori memorizzati nell'elenco

Ho pensato che ci sarebbe stato un modo semplice come un metodo .ToList() o di essere in grado di forzare attraverso le stringhe della classe (nessun pubblico GetEnumerator). Sono stato in grado di scoprire che Foreach nasconde un po 'di complessità ma non di fare ciò che voglio.

Ho cercato online senza alcun risultato (manca la terminologia corretta forse), purtroppo ho lasciato il mio C# libri di riferimento sul posto di lavoro:/

sarebbe molto apprezzare un puntatore nella giusta direzione, Grazie.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.IO; 
using System.Xml; 

namespace ThereIsOnlyRules 
{ 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     try 
     { 
      listBox1.Items.Clear(); 

      string path = "characterXML.xml"; 
      FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 
      System.Xml.XmlDocument CXML = new System.Xml.XmlDocument(); 

      CXML.Load(fs); 

      //Get the number of elements 
      XmlNodeList elemList = CXML.GetElementsByTagName("unit"); 

      //foreach (var element in elemList) 
      //{ 
      // listBox1.Items.Add(element); 
      //} 

      for (int i = 0; i < elemList.Count; i++) 
      { 
       UnitAttributes attributes = new UnitAttributes(); 

       attributes.army = elemList[i].Attributes["army"].Value; 
       attributes.category = elemList[i].Attributes["category"].Value; 
       attributes.type = elemList[i].Attributes["type"].Value; 
       attributes.composition = elemList[i].Attributes["composition"].Value; 
       attributes.WS = elemList[i].Attributes["WS"].Value; 
       attributes.BS = elemList[i].Attributes["BS"].Value; 
       attributes.T = elemList[i].Attributes["T"].Value; 
       attributes.W = elemList[i].Attributes["W"].Value; 
       attributes.I = elemList[i].Attributes["I"].Value; 
       attributes.A = elemList[i].Attributes["A"].Value; 
       attributes.LD = elemList[i].Attributes["LD"].Value; 
       attributes.save = elemList[i].Attributes["Save"].Value; 
       attributes.armour = elemList[i].Attributes["armour"].Value; 
       attributes.weapons = elemList[i].Attributes["weapons"].Value; 
       attributes.specialrules = elemList[i].Attributes["specialrules"].Value; 
       attributes.transport = elemList[i].Attributes["transport"].Value; 
       attributes.options = elemList[i].Attributes["options"].Value; 

       //foreach (string item in attributes) 
       //{ 

        //unit.Add(item); 
       //} 
       //listBox1.Items.AddRange(attributes) 

      } 

      //Close the filestream 
      fs.Close(); 
     } 
     catch (Exception ex) 
     { 

     } 
    } 
} 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ThereIsOnlyRules 
{ 
class UnitAttributes 
{ 
    public string army { get; set; } 
    public string category { get; set; } 
    public string type { get; set; } 
    public string composition { get; set; } 
    public string WS { get; set; } 
    public string BS { get; set; } 
    public string T { get; set; } 
    public string W { get; set; } 
    public string I { get; set; } 
    public string A { get; set; } 
    public string LD { get; set; } 
    public string save { get; set; } 
    public string armour { get; set; } 
    public string weapons { get; set; } 
    public string specialrules { get; set; } 
    public string transport { get; set; } 
    public string options { get; set; } 
    } 
} 

<?xml version="1.0"?> 
<config> 
<unit 
army="Tyranids" 
category="Troops" 
type="Infantry" 
composition="10-30" 
WS="3" 
BS="3" 
T="3" 
W="1" 
I="4" 
A="1" 
LD="6" 
Save="6+" 
armour="Chitin" 
weapons="Claws and Teeth, Fleshborer" 
specialrules="Instictive Behaviour - Lurk, Move Through Cover" 
transport="If the brood consists of 20 models or less, it may take a Mycetic Spore." 
options="Strangleweb, Spinefists, Spike rifle, Devourer, Adrenal Glands, Toxin Sacs" 
> 
Termagant Brood 
</unit> 
<unit 
army="Tyranids" 
category="Troops" 
type="Infantry" 
composition="10-30" 
WS="3" 
BS="3" 
T="3" 
W="1" 
I="5" 
A="2" 
LD="6" 
Save="6+" 
armour="Chitin" 
weapons="Scything Talons" 
specialrules="Instictive Behaviour - Feed, Bounding Leap, Fleet, Move Through Cover" 
transport="If the brood consists of 20 models or less, it may take a Mycetic Spore." 
options="Adrenal Glands, Toxin Sacs" 
> 
Hormagaunt Brood 
</unit> 
</config> 
+1

'XmlNodeList' implementa' IEnumerable', quindi il tuo 'foreach' dovrebbe funzionare. – svick

risposta

3

I membri dei campi o delle proprietà della classe? In ogni caso, un po 'di riflessione e Linq dovrebbero consentire di enumerare attraverso i membri dei dati della classe, dopo aver idratato un'istanza del file XML.

var fieldDictionary = 
    (from f in typeof(UnitAttributes).GetFields() 
    select new {Name = f.Name, Value = (string)(f.GetValue(attributes))}) 
    .ToDictionary(x=>x.Name, x=>x.Value); 

fieldDictionary è ora un Dictionary<string, string> (che è un IEnumerable<KeyValuePair<string, string>>), che dovrebbe essere adatto per il caricamento in un ListBox.

Essere informati; la riflessione è lenta. Sarebbe molto più preferibile per te modificare o estendere la tua classe UnitAttributes per implementare IEnumerable (probabilmente una Tupla, forse una KeyValuePair). Ti permetterebbe anche di enumerare le proprietà di un'istanza della classe esattamente nell'ordine che desideri, invece dell'ordine in cui sono definite, o da altri dati FieldInfo/PropertyInfo come il nome del campo.

Inoltre, tenere presente che un campo non è una proprietà e viceversa. Se hai un mix di proprietà e campi pubblici nella tua classe, ti consiglio vivamente di standardizzare l'uno o l'altro; altrimenti dovrai riflettere ENTRAMBI un elenco di proprietà e un elenco di campi usando due delle affermazioni Linq di cui sopra (ad un costo di circa il doppio del tempo di esecuzione), e non ci saranno possibilità che si trovino in qualsiasi definizione personalizzata ordine.

2

Potrai risparmiare un sacco di tempo e fatica, se si utilizza un comune serializzatore come XmlSerializer per gestire la conversione di oggetti da/per le stringhe. Non è necessario scrivere questo tipo di codice da zero.

+0

D'accordo, ma penso che il punto cruciale della domanda è come enumerare attraverso i dati in forma di oggetto, non XML. – KeithS

+0

Ho ancora apprezzato di essere stato detto, vorrei solo leggere qualcosa di simile altrove. – Amicable

Problemi correlati