Reputation: 1108
The code below currently works and loads XML into a class structure. This structure consists of a collection of items (items), each that have static properties and a collection that I use for a variable number of properties.
Two things I want to do: 1) I want to change the list into something that has a unique key. I tried a dictionary and that didn't work, maybe a HashSet...leading on to... 2) The key for the collection should be driven by the item's "id" XML attribute.
I can't quite figure it out, and trying to copy the KVP pattern I used for an items variable parameters does not work. It adds the items to "items" but they are all empty and the hash for the collection is not populated.
Help please
[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;
}
}
Here is the associated 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>
Upvotes: 1
Views: 692
Reputation: 34421
Try something like this. I changed StringReader to StreamReader just for my testing. You can change it back
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;
}
Upvotes: 1