Rooibos
Rooibos

Reputation: 1

Loading XML file and deserializing data as Dictionary in C#

I'm working on a personal localization project for strings where data is contained within XML files and deserialzed to a Dictionary.

Apart from the main XML file that holds stats, I hold the string data in separate files, loading in the specified language file in separately. I fetch the matching string data via the ID that is used as the key to display the string data in the correct language.

I'm a beginner to C# and serialization, and have already worked on a more simple version where the Dictionary was only an int key from an attribute and a string value. That works, and I'm trying to build off of that.

With this version, the value would be an object. I have tried wrapping the data in an additional element, but ideally I would like to avoid that to use less lines and make it easier for me to read and edit as the file gets larger.

XML File:

<DataStrings>
    <ItemString id="1">
        <Name>Item 1</Name>
        <ID>1</ID>
        <Description>Item 1's description</Description>
    </ItemString>

    <ItemString id="2">
        <Name>Berry</Name>
        <ID>2</ID>
        <Description>Item 2's description</Description>
    </ItemString>

    <ItemString id="3">
        <Name>Shotgun</Name>
        <ID>3</ID>
        <Description>Item 3's description</Description>
    </ItemString>
</DataStrings>

Applicable C# Code:

public IDictionary<int, Data> ItemStringData = new Dictionary<int, Data>();

public class ItemString {
    [XmlAttribute("id")]
    public int Key;

    // not sure what to put here
    public Data Value;
}


public class Data {
    [XmlElement("Name")]
    public string Name = null;

    [XmlElement("ID")]
    public int ID = 0;

    [XmlElement("Description")]
    public string Description;

}


public Dictionary<int, Data> LoadDictionary2(string path) {
    Dictionary<int, Data> dict = new Dictionary<int, Data> { };

    using (var reader = new StreamReader(path)) {
        XmlSerializer deserializer = new XmlSerializer(typeof(List<ItemString>), new XmlRootAttribute("DataStrings"));
        dict = ((List<ItemString>)deserializer.Deserialize(reader)).ToDictionary(x => x.Key, x => x.Value);
    }

    return dict;
}

After deserialization, the code successfully gets the id key for each item, but returns null for the value.

With this post I'm asking for advice on where to look next after a couple days of attempts. Is this even correct/efficient XML? Is this a valid way to store data? I'm more familiar with relating between MySQL databases, and querying with PHP.

Should I remove the ID attribute, and is it possible to build a Dictionary where the key is taken from the ID element and all of the data is contained within a class as the value?

More importantly, a push in the right direction would be amazing.

Upvotes: 0

Views: 409

Answers (1)

Matt
Matt

Reputation: 26971

Your [XmlAttribute("id")] is in the wrong class - it's an attribute of Data:

public class DataStrings
{
    [XmlElement("ItemString")]
    public List<Data> Value;
}

public class Data
{
    [XmlAttribute("id")]
    public int id;

    [XmlElement("Name")]
    public string Name = null;

    [XmlElement("ID")]
    public int ID = 0;

    [XmlElement("Description")]
    public string Description;

}

public Dictionary<int, Data> Main(string path)
{
    var stringReader = new StringReader("<DataStrings><ItemString id=\"1\"><Name>Item 1</Name><ID>1</ID><Description>Item 1's description</Description></ItemString><ItemString id=\"2\"><Name>Berry</Name><ID>2</ID><Description>Item 2's description</Description></ItemString><ItemString id=\"3\"><Name>Shotgun</Name><ID>3</ID><Description>Item 3's description</Description></ItemString></DataStrings>");
    XmlSerializer deserializer = new XmlSerializer(typeof(DataStrings), new XmlRootAttribute("DataStrings"));
    var dict = ((DataStrings)deserializer.Deserialize(stringReader)).Value.ToDictionary(x => x.id, x => new Data() { ID = x.ID, Name = x.Name, Description = x.Description });
    return dict;
}

Upvotes: 2

Related Questions