2017-05-07 9 views
1

以下のコードは現在動作し、XMLをクラス構造にロードしています。この構造体は、静的なプロパティを持つ項目(項目)の集合と、可変数のプロパティに使用するコレクションで構成されています。c#XMLを「Id」属性からキーが得られるユニークキー付きコレクションにデシリアライズ

2つのこと: 1)リストを一意のキーを持つものに変更したい。私は辞書を試してみましたが、うまくいきませんでした。おそらくHashSet ... 2)コレクションのキーは、アイテムの "id" XML属性によって駆動される必要があります。

私はそれを理解することができず、項目変数パラメータに使用したKVPパターンをコピーしようとすると機能しません。アイテムを「アイテム」に追加しますが、それらはすべて空であり、コレクションのハッシュには値が設定されません。ここで

ヘルプしてください

[XmlRoot("ItemsContainer")] 
public class Items 
{ 
    [XmlAttribute("Version")] 
    public string Version { get; set; } 

    [XmlArray("Items")] 
    [XmlArrayItem("Item")] 
    public List<Item> items = new List<Item>(); //TODO - The key in this collection should be unique and driven from an item's "Id" XML attribute 

    public static Items Load(string path) 
    { 
     var xml = Resources.Load<TextAsset>(path); 
     var serializer = new XmlSerializer(typeof (Items)); 
     var reader = new StringReader(xml.text); 
     var items = (Items) serializer.Deserialize(reader); 
     reader.Close(); 
     return items; 
    } 
} 


public class Item 
{ 
    //### Fixed Item Parameters 
    [XmlAttribute("Id")] 
    public int Id { get; set; } 

    [XmlElement("Name")] 
    public string Name { get; set; } 

    [XmlElement("Description")] 
    public string Description { get; set; } 

    [XmlElement("Value")] 
    public float Value { get; set; } 

    //### Variable Item Parameters as Key Value pairs. 
    [XmlArray("KVPS")] 
    [XmlArrayItem("KVP")] 
    public List<KeyValuePair<string, string>> KVPS { get; set; } //We will have cases were we don't want unique keys 
} 

[Serializable] 
public class KVP<K, V> 
{ 
    public K Key { get; set; } 
    public V Value { get; set; } 

    public KVP() 
    { 
    } 

    public KVP(K key, V value) 
    { 
     Key = key; 
     Value = value; 
    } 
} 

関連するXML

<?xml version="1.0" encoding="utf-8"?> 

<ItemsContainer Version="1.0"> 
    <Items> 

    <Item Id="100"> 
     <Name>Burger</Name> 
     <Description>The lovely tasting Big Mac</Description> 
     <Value>5.67</Value> 
    </Item> 

    <Item Id="101"> 
     <Name>Sammich</Name> 
     <Description>Ham and cheese</Description> 
     <Value>2.80</Value> 
    </Item> 

    <Item Id="102"> 
     <Name>Carling</Name> 
     <Description>Pint of carling</Description> 
     <Value>2.80</Value> 
     <KVPS> 
     <KVP> 
      <Key>alchohol</Key> 
      <Value>3.9</Value> 
     </KVP> 
     <KVP> 
      <Key>alchohol</Key> 
      <Value>4.9</Value> 
     </KVP> 
     <KVP> 
      <Key>alchohol</Key> 
      <Value>5.9</Value> 
     </KVP> 
     </KVPS> 
    </Item> 

    </Items> 
</ItemsContainer> 
+0

これで、作成した固有のキーをドライブするようにしますか? Idが複製されている場合、どのようにキーを一意に作成するのでしょうか?逆にIdが重複していなければ、それはユニークなので、なぜIdを使用しないのですか? – Snympi

+0

> IDを作成して、固有のキーを作成するようにしますか?はい、これは私の仕事で言及されました。 > IDが複製されたらどうなるでしょうか?私が言及したように、それは辞書に入っているので、同じ扱いです。 >どのようにキーを独自に作成する必要がありますか?キーは既にXMLで作成されているので、ここで心配はありません>逆に、IDが重複していなければ、それはユニークなので、なぜIDを使用しないのですか?それは私が私のOPで求めているものです –

答えて

1

はこのような何かを試してみてくださいです。私は単に私のテストのためにStreamReaderをStreamReaderに変更しました。あなたはそれを元に戻すことができます

public static Dictionary<int, Item> Load(string path) 
     { 
      //var xml = Resources.Load<TextAsset>(path); 
      XmlSerializer serializer = new XmlSerializer(typeof(Items)); 
      StreamReader reader = new StreamReader(path); 
      Items items = (Items)serializer.Deserialize(reader); 
      reader.Close(); 
      Dictionary<int, Item> dict = items.items.GroupBy(x => x.Id).ToDictionary(x => x.Key, y => y.FirstOrDefault()); 
      return dict; 
     } 
+0

これは厳密に私が解決策ではなく代替として見る最後に行った方法のタイプでした。私が言うのは、リストを辞書に直接コピーするのではなく、リストを辞書にコピーするための追加ステップが追加されたからです。 1つのステップでこれを行う1つの方法は、XDocumentを使用してXMLを手動で移動するか、またはIXmlSerializableを使用して同様のことを行うことです。しかし、私はこの範囲のために、これは解決策と考えるべきだと思います。 –

+0

items.items.GroupBy(x => x.Id).ToList()を使用して各項目を取得できます。リストを列挙して、それぞれを既存の辞書に追加します。追加(x.Key、x) – jdweng

関連する問題