使用列表反序列化对象列表

时间:2014-03-25 11:21:34

标签: c# xml list xml-deserialization

我有以下XML:

<?xml version="1.0" encoding="utf-8"?>
<CallEvents xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <CallEvent>
    <Time>2014-02-24T06:44:27.12</Time>
    <Type>Inner</Type>
    <Fs>
      <StrPair>
        <Key>Name</Key>
        <Value>Call1</Value>
      </StrPair>
      <StrPair>
        <Key>Owner</Key>
        <Value>Ali</Value>
      </StrPair>
    </Fs>
  </CallEvent>
  <CallEvent>
    <Time>2014-02-24T06:44:29.089</Time>
    <Type>Outer</Type>
    <Fs>
      <StrPair>
        <Key>Name</Key>
        <Value>Call2</Value>
      </StrPair>
      <StrPair>
        <Key>Id</Key>
        <Value>3242</Value>
      </StrPair>
      <StrPair>
        <Key>Another</Key>
        <Value>123</Value>
      </StrPair>
    </Fs>
  </CallEvent>
</CallEvents>

我尝试反序列化它,但它不想反序列化列表Fs。我得到CallEventsCallEvent项,CallEvent的成员填充了除列表Fs以外的正确值。列表Fs为空。为什么? 我做错了什么?

class Program
{
    static void Main(string[] args)
    {
        string xmlFile = "call_events.xml";
        CallEvents events = CallEvents.OpenFromXmlFile(xmlFile);
        Console.ReadKey();
    }
}

[Serializable]
public class CallEvent
{
    [XmlElement]
    public DateTime Time;
    [XmlElement]
    public CallEventType Type;

    public CallEvent()
    {
        this.Fields = new Dictionary<string, string>();
    }

    [XmlArray("Fs"), XmlArrayItem("StrPair")]
    public List<StrPair> Fs
    {
        get
        {
            var list = new List<StrPair>();
            foreach (var pair in Fields)
            {
                list.Add(new StrPair(pair.Key, pair.Value));
            }
            return list;
        }
        set
        {
            Fields.Clear();
            foreach (var dictPair in value)
            {
                Fields.Add(dictPair.Key, dictPair.Value);
            }
        }
    }

    [XmlIgnore]
    public Dictionary<string, string> Fields;

    public void ParseFields(List<LogMessage> eventLogMessages)
    {
        int eventLogMessagesCount = eventLogMessages.Count;
        this.Fields.Clear();
        for (int i = 0; i < eventLogMessagesCount; i++)
        {
            LogMessage logMessage = eventLogMessages[i];
            int pos = logMessage.Message.IndexOf(": ");
            if(pos == -1)
                continue;
            string fieldName = logMessage.Message.Substring(0, pos);
            pos+=2;
            string fieldValue = logMessage.Message.Substring(pos);
            if (this.Fields.ContainsKey(fieldName))
            {
                this.Fields[fieldName] += ("\r\n" + fieldValue);
            }
            else
            {
                this.Fields.Add(fieldName, fieldValue);
            }
        }
    }

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("{0} {1} | ", Type, Time);
        foreach (var pair in Fields)
        {
            sb.AppendFormat("{0}: {1}, ", pair.Key, pair.Value);
        }
        return sb.ToString();
    }

    [Serializable]
    public class StrPair
    {
        [XmlElement]
        public string Key;
        [XmlElement]
        public string Value;

        public StrPair() { }

        public StrPair(string key, string value)
        {
            Key = key;
            Value = value;
        }
    }
}

[XmlRoot("CallEvents")]
public class CallEvents : List<CallEvent>
{
    static public CallEvents OpenFromXmlFile(string xmlFileName)
    {
        CallEvents callEvents;// = new CallEvents();
        XmlSerializer ser = new XmlSerializer(typeof(CallEvents));
        XmlReader xmlReader = new XmlTextReader(xmlFileName);
        try
        {
            callEvents = (CallEvents)ser.Deserialize(xmlReader);
        }
        finally
        {
            xmlReader.Close();
        }
        return callEvents;
    }

    public void SaveToXmlFile(string xmlFileName)
    {
        XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
        xmlWriterSettings.Encoding = System.Text.Encoding.UTF8;
        xmlWriterSettings.Indent = true;

        XmlSerializer ser = new XmlSerializer(this.GetType());
        XmlWriter xmlWriter = null;
    tryAgain:
        try
        {
            xmlWriter = XmlTextWriter.Create(xmlFileName, xmlWriterSettings);
            ser.Serialize(xmlWriter, this);
        }
        catch (Exception ex)
        {
            System.Windows.Forms.DialogResult dr = System.Windows.Forms.MessageBox.Show("Couldn't serialize to XML. Details: " + ex.Message, "Error", System.Windows.Forms.MessageBoxButtons.RetryCancel, System.Windows.Forms.MessageBoxIcon.Warning);
            if (dr == System.Windows.Forms.DialogResult.Retry)
            {
                goto tryAgain;
            }
        }
        finally
        {
            if (xmlWriter != null)
            {
                xmlWriter.Close();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:-1)

我已经使用了一段时间,所以代码可能需要一些修改。

CallEvents events;

using(XmlReader reader = XmlReader.Create("call_events.xml"))
{
    XmlDeserializer deSerializer = new XmlDeserializer(typeof(CallEvents));
    events = (CallEvents)deSerializer.Deserialize(reader);
}