【问题标题】:XmlSerializer property converterXmlSerializer 属性转换器
【发布时间】:2011-08-23 05:37:45
【问题描述】:

假设我们有一个可以被 XmlSerializer 序列化/反序列化的类。应该是这样的:

[XmlRoot("ObjectSummary")]
public class Summary
{
     public string Name {get;set;}
     public string IsValid {get;set;}
}

我们有一个像这样的xml:

<ObjectSummary>
   <Name>some name</Name>
   <IsValid>Y</IsValid>
<ObjectSummary>

使用布尔属性 IsValid 而不是字符串属性是更好的决定,但在这种情况下,我们需要添加一些额外的逻辑来将数据从字符串转换为布尔值。

解决此问题的简单直接的方法是使用附加属性并将一些转换逻辑放入 IsValid getter。

谁能提出更好的决定?以某种方式或类似的方式在属性中使用类型转换器?

【问题讨论】:

  • 你的问题我不清楚。你为什么不使用布尔值?
  • OP 希望将 IsValid 设为布尔值,但输出 Y 和 N 而不是 false 和 true。
  • 这是一个关于 bool 的好问题 :) 我确实认为使用 bool 属性是一个非常合乎逻辑的决定,但不幸的是上面描述的 xml 来自外部系统,所以我没有能力改变任何东西。很可悲,不是吗? :)

标签: c# .net xml-serialization


【解决方案1】:

我这样做的方式 - 次优但没有找到更好的方法 - 是定义两个属性:

[XmlRoot("ObjectSummary")]
public class Summary
{
     public string Name {get;set;}
     [XmlIgnore]
     public bool IsValid {get;set;}
     [XmlElement("IsValid")]
     public string IsValidXml {get{ ...};set{...};}

}

用简单的代码替换 ... 以读取和写入 IsValid 值到 Y 和 N 并从中读取。

【讨论】:

    【解决方案2】:

    将节点视为自定义类型:

    [XmlRoot("ObjectSummary")]
    public class Summary
    {
        public string Name {get;set;}
        public BoolYN IsValid {get;set;}
    }
    

    然后在自定义类型上实现IXmlSerializable

    public class BoolYN : IXmlSerializable
    {
        public bool Value { get; set }
    
        #region IXmlSerializable members
    
        public System.Xml.Schema.XmlSchema GetSchema() {
            return null;
        }
    
        public void ReadXml(System.Xml.XmlReader reader) {
            string str = reader.ReadString();
            reader.ReadEndElement();
    
            switch (str) {
                case "Y":
                    this.Value = true;
                    break;
                case "N":
                    this.Value = false;
                    break;
            }
        }
    
        public void WriteXml(System.Xml.XmlWriter writer) {
            string str = this.Value ? "Y" : "N";
    
            writer.WriteString(str);
            writer.WriteEndElement();
        }
    
        #endregion
    }
    

    您甚至可以将该自定义类改为struct,并在它和bool 之间提供隐式转换,使其更加“透明”。

    【讨论】:

    • 很好的答案。但是,我不得不删除语句 writer.WriteEndElement();防止在 serializer.Serialize(...) 操作期间崩溃
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 2011-01-06
    • 2013-06-21
    • 1970-01-01
    相关资源
    最近更新 更多