XmlSerializer属性转换器

时间:2011-05-11 11:25:41

标签: c# .net xml-serialization

假设我们有一个可以由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中。

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

3 个答案:

答案 0 :(得分:11)

将节点视为自定义类型:

[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 :(得分:8)

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

[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 :(得分:-1)

using Newtonsoft.Json;

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


 //pass objectr of Summary class you want to convert to XML
 var json = JsonConvert.SerializeObject(obj);
 XNode node = JsonConvert.DeserializeXNode(json, "ObjectSummary");

如果您有多个对象,请将其放在列表中并序列化列表。

                dynamic obj = new ExpandoObject();
                obj.data = listOfObjects;
                var json = JsonConvert.SerializeObject(obj);
                XNode node = JsonConvert.DeserializeXNode(json, "ObjectSummary");