views:

114

answers:

4

Hey Team, I got a XML File, looking familiar to this :

<root>
 <carnumber>12</carnumber>
 <carcolor>2</carcolor>
 <cartype>5</cartype>
</root>

Like you see I got some Elements with values/text in it. The car element for example can take values from 1 to 1000. But the element carcolor can take values from 1 - 5 and the cartype from 1 - 10.

The important thing is that the values of the carcolor and cartype elements mean something. carcolor "2" means red, "1" blue and so on.

So I need to present the user not the values but the real meaning of the values.

I found myself creating some classes that represent the elements with there valid values and things got really complicated and I dont know if this was/is the best way.

A friend of mine suggested me to use XML serialization because my XML file is static. It will never change.

My question is simple. I just wanna know how you would solve this problem. My idea contains classes that represent the XML element, for example cartype within this class I have a Dictonary with a pair. This represent the values within the XML file and the string is the meaning of this value. And I use a lot of Linq to navigate and edit the values.

Thanks again!

A: 

Why not format your XML file more like:

<root>
 <carnumber code="2" name="John's Car"/>
 <carcolor code="3" name="Red"/>
 <cartype code="2" name="Hatchback"/>
</root>
Ben Robinson
The XML file is so given. I cant do any changes on it. But with a XSLT I could do that.
TomyTomy
+3  A: 

This can be as complicated or easy as you want it to be. I would, however, second your friends suggestion to use XML Serialization, something like:

[XmlRoot("Car")]
public class Car
{
     public Car() 
     {
     }

     [XmlElement("Number")]
     public int Number { get; set; }

     [XmlElement("Color")]
     public int Color { get; set; }

     [XmlElement("Type")]
     public int Type { get; set; }
}

Serialization:

Car myCar = new Car();
myCar.Number = 1;
myCar.Color = 2;
myCar.Type = 3;

XmlSerializer s = new XmlSerializer(typeof(Car));
TextWriter w = new StreamWriter( @"c:\Car.xml" );
s.Serialize(w, myCar);
w.Close();

Deserialization:

Car myCar;
TextReader r = new StreamReader("Car.xml");
myCar = (Car)s.Deserialize(r);
r.Close();

You could further improve this by exposing a custom enum for the likes of your Type field and internally serializing the number relating to it. Also perhaps exposing the Color enum for the car and internally storing a numerical value.

James
This would help me to load and save the file, yes. But what about the presentation of the data ?
TomyTomy
It depends on how you are implementing your forms. However, as basic as you can get, just display the values in Labels to start off with.
James
For Color you can create enum for above given solution.
Lalit
Also depends if it needs to be internationalized or if it's English only
slf
@slf yeah good point
James
+2  A: 

Give this a try:

[XmlRoot("root")]
public class Car
{
    private static XmlSerializer serializer = new XmlSerializer(typeof(Car));

    [XmlElement("carnumber")]
    public int Number { get; set; }

    [XmlElement("carcolor")]
    public int Color { get; set; }

    [XmlElement("cartype")]
    public int Type { get; set; }

    [XmlIgnore]
    public CarColor CarColor
    {
        get
        {
            return (CarColor)Color;
        }
        set
        {
            Color = (int)value;
        }
    }

    [XmlIgnore]
    public CarType CarType
    {
        get
        {
            return (CarType)Type;
        }
        set
        {
            Type = (int)value;
        }
    }

    public string CarColorString
    {
        get
        {
            return this.CarColor.ToString().Replace('_', ' ');
        }
    }

    public string CarTypeString
    {
        get
        {
            return this.CarType.ToString().Replace('_', ' ');
        }
    }

    public string Serialize()
    {
        StringBuilder sb = new StringBuilder();
        using (StringWriter writer = new StringWriter(sb))
        {
            serializer.Serialize(writer, this);
        }
        return sb.ToString();
    }

    public static Car Deserialize(string xml)
    {
        using (StringReader reader = new StringReader(xml))
        {
            return (Car)serializer.Deserialize(reader);
        }
    }
}

public enum CarColor
{
    Red = 1,
    Blue = 2,
    Green = 3,
    Light_Brown = 4
    // and so on...
}

public enum CarType
{
    Sedan = 1,
    Coupe = 2,
    Hatchback = 3,
    SUV = 4,
    Pickup_Truck = 5
    // and so on...
}

I've added some enums to allow for presentation.

You can set the values of a Car and serialize it to an xml string:

Car car = new Car();
car.Number = 1;
car.CarColor = CarColor.Blue;
car.CarType = CarType.Coupe;
string xml = car.Serialize();

And deserialize an xml string into a car:

string example = 
@"<root>
 <carnumber>12</carnumber>
 <carcolor>2</carcolor>
 <cartype>5</cartype>
</root>";

Car car = Car.Deserialize(example);

For presentation, you can use the CarColorString and CarTypeString properties, which, in case your enum values contain more than one word, replace underscores with spaces.

Console.WriteLine(car.CarColorString);
Console.WriteLine(car.CarTypeString);
fre0n
Thanks, this give me the right push :D
TomyTomy
A: 

I would build the UI in WPF, not WinForms. Set up a data context that binds to the XML as an XML data source, write type converters to round trip the data between the internal and human-readable values, bind combo boxes to the various elements, and Bob's your uncle.

I recognize that this answer isn't very useful to you if you're not using WPF.

Robert Rossney
And so do I. Sadly :(
TomyTomy