2011-05-11 51 views
10

假设我们有一个可以被XmlSerializer序列化/反序列化的类。它会像这样: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获取器中。

任何人都可以提出更好的决定吗?以某种方式在属性中使用类型转换器或类似的东西?

+1

你的问题不清楚给我。你为什么不使用布尔? – bnieland 2011-05-11 11:29:42

+2

OP希望将IsValid作为布尔值,但输出Y和N而不是假和真。 – Aliostad 2011-05-11 11:36:00

+0

这是一个关于bool的好问题:)我确实认为使用bool属性是一个非常合理的决定,但不幸的是上述xml来自外部系统,所以我无法更改任何内容。很伤心,不是吗? :) – madcyree 2011-05-11 14:06:15

回答

10

对待节点作为一个自定义类型:

[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使它更加“透明”。

+1

很好的答案。但是,我不得不删除语句writer.WriteEndElement();以防止serializer.Serialize(...)操作期间发生崩溃 – Hadron 2015-11-20 03:08:56

7

我做到这一点 - 这是次优但还没有找到更好的办法 - 就是定义两个属性:

[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并从中读取。