简体   繁体   English

XmlSerializer 属性转换器

[英]XmlSerializer property converter

Suppose we have a class which can be serialized/deserialized by XmlSerializer.假设我们有一个可以被 XmlSerializer 序列化/反序列化的类。 It would be like so:它会是这样的:

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

We have an xml which will be like so:我们有一个像这样的 xml:

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

Using of boolean property IsValid instead of string property is much better decision, but in this case we need to add some additional logic to convert data from string to bool.使用布尔属性 IsValid 而不是字符串属性是更好的决定,但在这种情况下,我们需要添加一些额外的逻辑来将数据从字符串转换为布尔值。

The simple and direct way to solve this problem is to use additional property and put some conversion logic into the IsValid getter.解决这个问题的简单直接的方法是使用额外的属性,并在 IsValid getter 中放入一些转换逻辑。

Can anyone suggest a better decision?谁能建议一个更好的决定? To use a type converter in attributes somehow or something similar?以某种方式在属性中使用类型转换器或类似的东西?

Treat the node as a custom type:将节点视为自定义类型:

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

Then implement IXmlSerializable on the custom type:然后在自定义类型上实现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
}

You can even make that custom class a struct instead, and provide implicit conversions between it and bool to make it even more "transparent".您甚至可以将该自定义类改为struct ,并在它和bool之间提供隐式转换以使其更加“透明”。

The way I do it - which is suboptimal but have not found a better way - is to define two properties:我这样做的方式 - 这是次优但还没有找到更好的方法 - 是定义两个属性:

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

}

Replace ... with the simple code to read and write the IsValid value to Y and N and read from it.将 ... 替换为简单的代码,以将 IsValid 值读取和写入 Y 和 N 并从中读取。

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

If you have more than one object, put it inside a list and Serialize List.如果您有多个对象,请将其放入列表并序列化列表。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM