【问题标题】:Simple C# Xml Serialization简单的 C# Xml 序列化
【发布时间】:2010-09-02 09:43:21
【问题描述】:

我有一堂课:

public class Car {

   public string Model {get;set;}

   public string SeatFinish {get;set;}

   public string Audio {get;set;}
}

我想使用xml序列化属性将其序列化为下面的xml

<Car>
  <Model>name</Model>
  <Options>
   <SeatFinish>Leather</SeatFinish>
   <Audio>5 speaker</Audio>
  </Options>
</Car>

由于项目特定的原因,我不能只创建一个属性:

public List<string> Options; 

有没有办法通过属性指定在某个 xml 元素下序列化属性(在本例中为“选项”节点)?我可以编写一个允许这样做的自定义属性吗?任何建议表示赞赏。

编辑:

我看到有一个选项类会起作用,但是有没有办法在不创建其他类的情况下实现这一点?例如,我可能只想对一个属性执行此操作。

理想情况下我希望能够指定

[Parent("Options")]
public string SeatFinish {get;set;}

【问题讨论】:

    标签: c# .net xml xml-serialization c#-4.0


    【解决方案1】:

    这是域模型的一部分还是类似的?听起来您希望这些选项可以在汽车对象之外重用,那么为什么不创建一个单独的 Options 类呢?

    public class Options
    {
       public string SeatFinish {get;set;}
       public string Audio {get;set;}
    }
    

    并将您的 Car 类更改为 Options 类:

    public class Car 
    {
       public string Model {get;set;}
       public Options Options {get;set;}
    }
    

    【讨论】:

    • 我知道这会起作用,但是有没有办法在不创建选项类的情况下做到这一点?
    • 我从未遇到过仅使用属性的方法。
    【解决方案2】:

    如果可能,请尝试将类更改为:

    public class Car {
    
        public class CarOptions
        {
            public string SeatFinish { get; set; }
            public string Audio { get; set; }
        }
    
        public string Model { get; set; }
        public CarOptions Options { get; set; }
    
        public Car()
        {
            this.Options = new CarOptions();
        }
    }
    

    【讨论】:

    • private set; 与反序列化不兼容。
    【解决方案3】:

    我相信要得到你想要的,你需要自己实现 IXmlSerializable 并序列化对象。

    请参阅:Custom XML Serialization

    首先实现接口:

    public class Car : IXmlSerializable
    {
        // Private state
        public string Model { get; set; }
        public string SeatFinish { get; set; }
        public string Audio { get; set; }
    
        public Car()
        {
            Model = "Toyota";
            SeatFinish = "Leather";
            Audio = "Awesome Soundz";
        }
    

    ...

    然后实现您的自定义序列化。 XmlWriter 类下有很多方法可以快速智能地创建 XML,但是为了简单起见,我在这里使用了 WriteRaw()。

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteRaw("<Model>" + this.Model + "</Model>");
            writer.WriteRaw("<Options>");
            writer.WriteRaw("<SeatFinish>" + this.SeatFinish + "</SeatFinish>");
            writer.WriteRaw("<Audio>" + this.Audio + "</Audio>");
            writer.WriteRaw("</Options>");
        }
    
        public void ReadXml(XmlReader reader) { ... }
    }
    

    然后实现相应的 ReadXml() 方法来反序列化您的 XML 对象表示。我建议使用 System.Xml.XPath.XPathNavigator 类来简化 XML 反序列化的工作,但无论如何,XMLReader 类中有很多普通的旧方法,你可能会为一个人为的例子工作。

    【讨论】:

    • 似乎您几乎不需要求助于 WriteRaw。你在这里没有正确地转义 -anything-,你最终会生成无效的 XML。
    【解决方案4】:

    我认为您正在使用默认的 XML 序列化机制。在这种情况下,请查看IXmlSerializable Interface。它允许将序列化挂钩添加到现有的 XML 序列化机制中。然后,您可以修改 XML 表示,而无需触及现有的对象模型。

    【讨论】:

      【解决方案5】:

      看看这个之前的帖子。

      C# Serialization XML

      我相信将它与 GenericTypeTea 所说的混合是最好的。

      希望对你有帮助。

      【讨论】:

        猜你喜欢
        • 2010-12-27
        • 2020-07-10
        • 2015-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多