【问题标题】:Best way to present the user the XML values of a file?向用户展示文件的 XML 值的最佳方式是什么?
【发布时间】:2010-01-18 15:33:09
【问题描述】:

我有一个 XML 文件,看起来很熟悉:

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

如您所见,我得到了一些带有值/文本的元素。例如 car 元素可以取 1 到 1000 之间的值。但是 carcolor 元素可以取 1 到 5 之间的值,而 cartype 可以取 1 到 10 之间的值。

重要的是 carcolor 和 cartype 元素的值是有意义的。 carcolor "2" 表示红色,"1" 表示蓝色等等。

所以我需要向用户展示的不是价值观,而是价值观的真正含义。

我发现自己创建了一些类来表示具有有效值的元素,事情变得非常复杂,我不知道这是否是最好的方法。

我的一个朋友建议我使用 XML 序列化,因为我的 XML 文件是静态的。它永远不会改变。

我的问题很简单。我只是想知道你将如何解决这个问题。我的想法包含表示 XML 元素的类,例如这个类中的 cartype 我有一个带有一对的字典。这表示 XML 文件中的值,字符串是该值的含义。我使用了很多 Linq 来导航和编辑值。

再次感谢!

【问题讨论】:

  • 另外,我必须让用户有机会编辑这些值,就像你知道的那样,以一种用户友好的方式。这意味着如果用户想要编辑颜色,我必须代表所有有效的颜色。就像一个具有以下值的组合框:“Blue”,“Red”......但我必须再次从中生成一个有效的 XML。
  • XML 文件是这样给出的。我无法对其进行任何更改。

标签: c# xml linq xml-serialization


【解决方案1】:

这可以像您希望的那样复杂或简单。但是,我会支持您朋友使用 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; }
}

序列化:

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();

反序列化:

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

您可以通过为 Type 字段之类的类似字段公开自定义枚举并在内部序列化与其相关的数字来进一步改进这一点。也可能会暴露汽车的Color 枚举并在内部存储一个数值。

【讨论】:

  • 这将帮助我加载和保存文件,是的。但是数据的呈现方式呢?
  • 这取决于你如何实现你的表单。但是,尽可能基本,只需在 Labels 中显示值即可。
  • 对于颜色,您可以为上述解决方案创建枚举。
  • 还取决于它是需要国际化还是只有英文
【解决方案2】:

试试这个:

[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...
}

我添加了一些枚举以进行演示。

您可以设置 Car 的值并将其序列化为 xml 字符串:

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

并将一个 xml 字符串反序列化为汽车:

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

Car car = Car.Deserialize(example);

为了演示,您可以使用 CarColorString 和 CarTypeString 属性,如果您的枚举值包含多个单词,请将下划线替换为空格。

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

【讨论】:

    【解决方案3】:

    为什么不将您的 XML 文件格式化为:

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

    【讨论】:

    • XML 文件是这样给出的。我无法对其进行任何更改。但是使用 XSLT 我可以做到这一点。
    【解决方案4】:

    我会在 WPF 中构建 UI,而不是 WinForms。设置作为 XML 数据源绑定到 XML 的数据上下文,编写类型转换器以在内部值和人类可读值之间来回传输数据,将组合框绑定到各种元素,Bob 就是你的叔叔。

    我知道如果您不使用 WPF,这个答案对您来说不是很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-26
      相关资源
      最近更新 更多