简体   繁体   English

向用户显示文件的XML值的最佳方法是什么?

[英]Best way to present the user the XML values of a file?

I got a XML File, looking familiar to this : 我有一个XML文件,看起来很熟悉:

<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. 例如,car元素可以取1到1000之间的值。但是carcolor元素可以取值为1到5,而cartype取值为1到10。

The important thing is that the values of the carcolor and cartype elements mean something. 重要的是carcolor和cartype元素的值意味着什么。 carcolor "2" means red, "1" blue and so on. carcolor“2”表示红色,“1”表示蓝色,依此类推。

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. 我的一个朋友建议我使用XML序列化,因为我的XML文件是静态的。 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. 我的想法包含代表XML元素的类,例如这个类中的cartype我有一对Dictonary。 This represent the values within the XML file and the string is the meaning of this value. 这表示XML文件中的值,字符串是此值的含义。 And I use a lot of Linq to navigate and edit the values. 我使用了很多Linq来导航和编辑值。

Thanks again! 再次感谢!

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: 但是,我会建议朋友使用XML序列化,例如:

[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. 您可以通过为Type字段之Type的公开自定义枚举并在内部序列化与其相关的数字来进一步改进此功能。 Also perhaps exposing the Color enum for the car and internally storing a numerical value. 也许可以为汽车公开Color enum并在内部存储数值。

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的值并将其序列化为xml字符串:

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: 并将xml字符串反序列化为汽车:

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. 对于演示,您可以使用CarColorString和CarTypeString属性,如果您的枚举值包含多个单词,则使用空格替换下划线。

Console.WriteLine(car.CarColorString);
Console.WriteLine(car.CarTypeString);

Why not format your XML file more like: 为什么不格式化XML文件更像:

<root>
 <carnumber code="2" name="John's Car"/>
 <carcolor code="3" name="Red"/>
 <cartype code="2" name="Hatchback"/>
</root>

I would build the UI in WPF, not WinForms. 我会在WPF中构建UI,而不是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. 设置一个数据上下文,它将XML绑定为XML数据源,写入类型转换器以在内部和人类可读值之间往返数据,将组合框绑定到各种元素,Bob是你的叔叔。

I recognize that this answer isn't very useful to you if you're not using WPF. 我认识到如果您不使用WPF,这个答案对您来说并不是很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM