解析Xml文档中的指数值

Ado*_*adh 5 c#

我在反序列化对象时遇到问题(我无法修改)。我收到了某些 xml 元素的指数值,并且为了在我的类中表示它们,我使用了十进制值,预计当我反序列化 xml 文档时它会失败。

<fwdRate>-9.72316862724032E-05</fwdRate>
Run Code Online (Sandbox Code Playgroud)

除了在我的类中创建 2 个属性来表示它(一个字符串,另一个是十进制值)之外,还有其他解决方案来表示此属性吗?

我可以为十进制值创建自定义反序列化类吗?

        private void ParseXML(string value)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(SwapDataSynapseResult));
            using (TextReader reader = new StringReader(value))
            {
                _result = serializer.Deserialize(reader) as SwapDataSynapseResult;
            }
        }
Run Code Online (Sandbox Code Playgroud)

作为需求

using System;
using System.IO;
using System.Xml.Serialization;

[XmlRoot(ElementName = "result")]
public class Result
{
    [XmlElement(ElementName = "fwdRate")]
    public decimal FwdRate { get; set; }
}       
public class Program
{
    public static void Main()
    {
         string val = "<result><fwdRate>-9.72316862724032E-05</fwdRate></result>";
         Result response = ParseXML(val);
  }
  static Result ParseXML(string value)
  {
      XmlSerializer serializer = new XmlSerializer(typeof(Result));
      using (TextReader reader = new StringReader(value))
      {
         return serializer.Deserialize(reader) as Result;
      }
  }

}
Run Code Online (Sandbox Code Playgroud)

Ora*_*ace 6

在 XML 中,十进制值不允许使用科学(指数)表示法(请参阅“限制”段落中的此链接)。

任何一个:

  • 该值确实是一个浮点一:在代码中用float/double代替 a 。decimal
  • XML 已损坏。

同样,在 C# 中,默认情况下,Decimal.Parse不接受指数表示。您可以通过实现一个包装 a 的新结构来覆盖此行为,并在反序列化时decimal实现并允许指数表示:IXmlSerializable

public struct XmlDecimal : IXmlSerializable
{
    public decimal Value { get; private set; }

    public XmlDecimal(decimal value) => Value = value;

    public XmlSchema GetSchema() => null;

    public void ReadXml(XmlReader reader)
    {
        var s = reader.ReadElementContentAsString();
        Value = decimal.TryParse(s, NumberStyles.Number | NumberStyles.AllowExponent,
            NumberFormatInfo.InvariantInfo, out var value)
            ? value
            : 0; // If parse fail the resulting value is 0. Maybe we can throw an exception here.
    }

    public void WriteXml(XmlWriter writer) => writer.WriteValue(Value);

    public static implicit operator decimal(XmlDecimal v) => v.Value;

    public override string ToString() => Value.ToString();
}
Run Code Online (Sandbox Code Playgroud)

缺陷是您必须使用此结构而不是decimal模型中的任何位置。

遗憾的是,您不能将此结构设置为只读,已在此处进行了解释。