How to XML-serialize a dictionary

前端 未结 5 508
执笔经年
执笔经年 2020-11-29 07:16

I have been able to serialize an IEnumerable this way:

[XmlArray(\"TRANSACTIONS\")]
[XmlArrayItem(\"TRANSACTION\", typeof(Record))]
public IEnumerable

        
5条回答
  •  遥遥无期
    2020-11-29 07:57

    If you are learning C# you might as well create a class with the logic you want. In this example I made a ProgressiveTax object that you can call .Evaluate() with to calculate taxes.

    You can also write or read from XML strings (which can be written to files)

    For example, first populate the tax brackets from PAYE information provided and save to a file PAYE.xml. Then forget the tax brackets (out of scope from { }). And then read the file to populate the tax table from a file

    static class Program
    {
        static void Main(string[] args)
        {
            {   
                // create a tax table and save it to a file
                var tax = ProgressiveTax.PAYE();
                File.WriteAllText("PAYE.xml", tax.ToXml());
            }
            {   
                // read a tax table from a file
                var tax = ProgressiveTax.FromXml(File.ReadAllText("PAYE.xml"));
    
                // use the tax table
                var x = tax.Evaluate(42250m);
                Debug.WriteLine($"Tax={x}");
            }            
        }
    }
    

    The xml file looks like this, which can be edited manually, or be generated from a database/webservice.

    
    
      
        
          0
          0.1
        
        
          24000
          0.15
        
        
          40667
          0.2
        
        
          57334
          0.25
        
      
    
    

    and the class that actually holds the tax information and calculates the tax amount

    public class ProgressiveTax
    {
        public ProgressiveTax()
        {
            this.Table = new SortedDictionary();
        }
        public ProgressiveTax(SortedDictionary table)
        {
            this.Table = table;
        }
    
        public static ProgressiveTax PAYE()
        {
            var tax = new ProgressiveTax();
            tax.Credit = 2400m;
            tax.Table[0m] = 0.1f;
            tax.Table[24000m] = 0.15f;
            tax.Table[40667m] = 0.20f;
            tax.Table[57334m] = 0.25f;
            return tax;
        }
    
        public string ToXml()
        {
            var fs = new StringWriter();
            var xs = new XmlSerializer(typeof(ProgressiveTax));
            xs.Serialize(fs, this);
            fs.Close();
            return fs.ToString();
        }
    
        public static ProgressiveTax FromXml(string xml)
        {
            var fs = new StringReader(xml);
            var xs = new XmlSerializer(typeof(ProgressiveTax));
            var tax = xs.Deserialize(fs) as ProgressiveTax;
            fs.Close();
            return tax;
        }
    
        [XmlAttribute]
        public decimal Credit { get; set; }
      
        [XmlIgnore()]  
        SortedDictionary Table { get; }
    
        [XmlArrayItem(ElementName = "Bracket")]
        public (decimal lower, float rate)[] Brackets
        {
            get
            {
                var parts = new (decimal lower, float rate)[Table.Count];
                int index = 0;
                foreach (var item in Table)
                {
                    parts[index++] = (item.Key, item.Value);
                }
                return parts;
            }
            set
            {
                Table.Clear();
                foreach (var (lower, rate) in value)
                {
                    Table[lower] = rate;
                }
            }
        }
    
        public decimal Evaluate(decimal income)
        {
            decimal result = -Credit;
            foreach (var item in Table.Reverse())
            {
                if (item.Key <= income)
                {
                    Debug.WriteLine($"Assess {item.Value:P2} tax on {income - item.Key}");
                    result += (decimal)( item.Value * (float) (income - item.Key));
                    income = item.Key;
                }
            }
            return Math.Max(0m, result);
        }
    }
    

    The sample program produces the following output in the debugger.

    Assess 20.00% tax on 1583
    Assess 15.00% tax on 16667
    Assess 10.00% tax on 24000
    Tax=2816.65
    

    If you add up 1583 + 16667 + 24000 = 42250 which the total amount of income. Since this is a progressive tax, the above rates and amounts are used, and then 2400 is credited. Also not the result must be 0 or positive.

提交回复
热议问题