2012-02-07 24 views
6

Bu, bir XML dosyasındaki bir değerler kümesini yükler ve bunları bir depolama alanına yerleştirir. Değerleri liste olarak nasıl çıkaracağımı anlamaya çalışıyorum, böylece bunları bir Liste Kutusuna yerleştirebiliyorum.Saklanan Değerlerin Sınıfını Listeleme Çıktısı

Bir .ToList() yöntemi gibi kolay bir yol olacağını veya sınıftaki dizelerle (herkese açık GetEnumerator yok) başarabileceğini düşündüm. Foreach'ın karmaşıklığın bir kısmını gizlediğini, ancak istediğimi yapmak için uzak olmadığını fark ettim.

ben (belki doğru terminolojiyi eksik) boşuna online arama oldum, ne yazık ki iş yerinde benim C# referans kitapları bıraktı:/

, doğru yönde Teşekkür bir işaretçi takdir çok istiyorum.

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 'IEnumerable' öğesini uygular, bu nedenle foreach'iniz çalışmalıdır. – svick

cevap

3

Sınıf alanlarınızın veya özelliklerin üyeleri misiniz? Her iki durumda da, küçük bir yansıma ve Linq, bir örneğini XML dosyanızdan hiddetledikten sonra sınıfınızın veri üyeleri arasında numaralandırmanıza izin vermelidir.

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 artık bir liste kutusu içine yüklenmesi için uygun olmalıdır, (bir IEnumerable<KeyValuePair<string, string>> olan) Dictionary<string, string>.

Dikkat! yansıma yavaştır. IEnumerable (muhtemelen bir Tuple, belki de bir KeyValuePair) uygulamak için UnitAttributes sınıfınızı değiştirmeniz veya genişletmeniz çok daha fazla tercih edilir. Ayrıca, sınıfın bir örneğinin özelliklerini, tanımlandıkları sıra yerine tam olarak istediğiniz sırada veya alanın adı gibi başka bir FieldInfo/PropertyInfo verileriyle numaralandırmanıza izin verir. Ayrıca, bir alanın bir özellik olmadığının ve bunun tersinin de farkında olun. Sınıfınızda mülkler ve kamu alanları karışımı varsa, bir veya diğerine standartlaştırmayı şiddetle öneririm; aksi halde, yukarıdaki Linq ifadelerinin ikisini (çalışma süresinin yaklaşık iki katı bir bedelle) kullanarak mülklerin listesini ve alanların listesini yansıtabilirsiniz ve bunların herhangi bir özel tanımlanmış olma şansı olmayacaktır. sipariş. Eğer dizeleri gidiş/nesneleri dönüştürme işlemek için XmlSerializer gibi ortak serileştirici kullanırsanız

2

Kendine zaman ve çaba tasarruf edersiniz. Bu tür kodu sıfırdan yazmak zorunda değilsiniz.

+0

Anlaştık ama bence soruların özü, XML biçiminde değil, nesne biçimindeki verilerle nasıl numaralandırılacağıdır. – KeithS

+0

Hala anlatılmayı takdir ediyorum, başka bir yerde benzer şeyler okuyordum. – Amicable