实现复合数据类型的自定义 XML 序列化/反序列化? [英] Implementing Custom XML Serialization/Deserialization of compound data type?

查看:63
本文介绍了实现复合数据类型的自定义 XML 序列化/反序列化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的应用程序中,我们有一个 Money 类型,它包含一个金额(十进制)和一个货币代码(字符串).在简单的形式中,它看起来像这样:

In our application, we have a Money type, which contains an amount (decimal) and a currency code (string). In simple form, it looks like this:

public class Money
{
  public decimal Amount{get;set;}
  public string CurrencyCode{get;set;}
}

正如您想象的那样,这在应用程序的许多地方都被使用,并且在发送到/从客户端发送时经常被序列化/反序列化.Money 金额通常被序列化为复合值,例如1.23USD"代表 1.23 美元.旧客户端 (HTML/JS) 会将该值解析为它的组成部分,返回到 Money 类型.Money 值作为元素值和属性值发送,具体取决于它们在应用程序中的位置,例如:

As you might imagine, this gets used in many places in the application, and is frequently serialized/deserialized as it is sent to/from the client. The Money amount is typically serialized as a compound value, e.g. "1.23USD" to represent $1.23. The old client (HTML/JS) would parse that value into its component parts back into the Money type. Money values are sent as element values, and as attribute values, depending on where they are in the app, e.g:

<SomeClass moneyValue="1.23USD" ... />

 <SomeClass>
<MoneyValue>1.23USD</MoneyValue>
...
</SomeClass>

我试图找出一种方法,我可以使用内置的 C#/.NET Xml 序列化工具来实现相同的行为.我查看了实现 ISerializable,但一直无法找到正确的方法.

I am trying to figure out a way that I can use the built-in C#/.NET Xml Serialization tools to have this same sort of behavior. I looked at implementing ISerializable, but haven't been able to figure out quite the correct way to do so.

本质上,我希望能够通过我自己的自定义逻辑反序列化 Money 金额(知道如何将1.23USD"解析为 Money 金额),并将其序列化为简单的字符串,例如1.23 美元"

Essentially, I want to be able to have the Money amount deserialized by custom logic of my own (that knows how to parse "1.23USD" into a Money amount), and serialize it to the simple string, e.g. "1.23USD"

最终目标是能够将类中的 Money 金额设为:

The end goal would be to able to have the Money amount in a class as either:

[XmlAttribute]
public Money SomeField // SomeField='123.USD

或:

[XmlElement]
public Money SomeOtherField //<SomeOtherField>1.23USD</SomeOtherField>

就像使用 int、string、double 等简单类型一样.

just the same way you can do that with simple types like int, string, double, etc.

这可能吗?

推荐答案

以下代码可以解决问题:

The following code does the trick:

public class Money
{
    public decimal Amount { get; set; }
    public string CurrencyCode { get; set; }
}

public class SomeClass
{
    public SomeClass() { }

    [XmlIgnore]
    public Money WrappedMoney { get; set; }

    [XmlAttribute]
    public string moneyValue
    {
        get
        {
            return String.Format("{0:.##}{1}", WrappedMoney.Amount, WrappedMoney.CurrencyCode);
        }
    }

}

public class ParentClass
{
    public SomeClass SomeClass {get; set;}
}

class Program
{
    public static int Main(string[] args)
    {
        var parent = new ParentClass
        {
            SomeClass = new SomeClass
            {
                WrappedMoney = new Money { Amount = 1.25M, CurrencyCode = "USD" }
            }
        };

        var serializer = new XmlSerializer(typeof(ParentClass));

        using (var writer = new StreamWriter("output.xml"))
        {
            serializer.Serialize(writer, parent);
        }

        return 0;
    }
}

XML 输出为:

<?xml version="1.0" encoding="utf-8"?>
<ParentClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <SomeClass moneyValue="1.25USD" />
</ParentClass>

这篇关于实现复合数据类型的自定义 XML 序列化/反序列化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆