C# 将xml反序列化为对象列表

C# 将xml反序列化为对象列表,c#,xml,C#,Xml,我正在尝试将一些xml反序列化为对象列表 我遇到的问题是事件对象中的辅助对象资源没有填充值。关于更多的背景,这是一个unity项目,我正在反序列化可能发生的随机事件列表 下面是我正在测试的XML: <?xml version='1.0'?> <Events> <Event> <Description> this is a test </Description> <Reward>

我正在尝试将一些xml反序列化为对象列表

我遇到的问题是事件对象中的辅助对象资源没有填充值。关于更多的背景,这是一个unity项目,我正在反序列化可能发生的随机事件列表

下面是我正在测试的XML:

<?xml version='1.0'?>
<Events>
  <Event>
    <Description>
      this is a test
    </Description>
    <Reward>
        <Food>
          0
        </Food>
        <Energy>
          1
        </Energy>
        <Happiness>
          2
        </Happiness>
        <ShipHp>
          3
        </ShipHp>
        <Garbage>
          4
        </Garbage>
    </Reward>
    <Cost>
        <Food>
          0
        </Food>
        <Energy>
          1
        </Energy>
        <Happiness>
          2
        </Happiness>
        <ShipHp>
          3
        </ShipHp>
        <Garbage>
          4
        </Garbage>
    </Cost>
    <EventType>
      Good
    </EventType>
    <EventId>
      1
    </EventId>
  </Event>
  <Event>
    <Description>
      this is a test
    </Description>
    <Reward>
        <Food>
          0
        </Food>
        <Energy>
          1
        </Energy>
        <Happiness>
          2
        </Happiness>
        <ShipHp>
          3
        </ShipHp>
        <Garbage>
          4
        </Garbage>
    </Reward>
    <Cost>
        <Food>
          0
        </Food>
        <Energy>
          1
        </Energy>
        <Happiness>
          2
        </Happiness>
        <ShipHp>
          3
        </ShipHp>
        <Garbage>
          4
        </Garbage>
    </Cost>
    <EventType>
      Good
    </EventType>
    <EventId>
      1
    </EventId>
  </Event>
</Events>
这是我的反序列化代码:

   public class EventHandler : MonoBehaviour
{

    [XmlInclude(typeof(Event))]
    [XmlInclude(typeof(Resources))]
    [Serializable, XmlRoot("Events")]
    public class EventData
    {
        [XmlElement("Event")]
        public List<Event> Events { get; set; }

        public EventData()
        {
            List<Event> Events = new List<Event>();
        }
    }

    List<Event> Events = new List<Event>();
    public static EventHandler instance;

    // Use this for initialization, called on script enabling
    void Start()
    {

        var serializer = new XmlSerializer(typeof(EventData));
        try
        {
            string xml = File.ReadAllText("Assets/TextResources/Events.xml");
            xml = xml.Replace("\n", string.Empty);
            xml = xml.Replace("\r", string.Empty);
            xml = xml.Replace("\t", string.Empty);
            using (var stringReader = new StringReader(xml))
            {
                using (var reader = XmlReader.Create(stringReader))
                {
                    var result = (EventData)serializer.Deserialize(reader);
                    Events = result.Events;

                }
            }
        }
        catch(Exception ex)
        {
            Debug.Log(ex);
        }
    }
}

因此,从这段代码中,我的事件对象将填充Description、EventType和EventId的值,但是报酬和成本资源对象没有填充这些值,到目前为止,我不知道为什么会这样。为了获得额外的分数,我也在努力寻找一种方法,简单地删除解析字符串时产生的所有死区。ie Good已更改为\n\r Good。

您的XML无效。您的第一个资源标签从未关闭。

确定。所以我找到了问题的解决方案,我不是这方面的专家,因为如果有更多有经验的人想要添加任何更正来改进代码,我很乐意进行更改

首先,我的XML有一个格式化问题,为了找到这个问题,我实际上序列化了一个事件对象列表,并使用结果文本来找到解决方案,下面是修订后的文本:

<ArrayOfEvent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Event>
    <Description>abc</Description>
    <Reward>
      <Food>0</Food>
      <Happiness>2</Happiness>
      <Energy>1</Energy>
      <ShipHp>3</ShipHp>
      <Garbage>4</Garbage>
    </Reward>
    <Cost>
      <Food>0</Food>
      <Happiness>2</Happiness>
      <Energy>1</Energy>
      <ShipHp>3</ShipHp>
      <Garbage>4</Garbage>
    </Cost>
    <EventId>1</EventId>
    <EventType>Good</EventType>
  </Event>
  <Event>
    <Description>def</Description>
    <Reward>
      <Food>0</Food>
      <Happiness>2</Happiness>
      <Energy>1</Energy>
      <ShipHp>3</ShipHp>
      <Garbage>4</Garbage>
    </Reward>
    <Cost>
      <Food>0</Food>
      <Happiness>2</Happiness>
      <Energy>1</Energy>
      <ShipHp>3</ShipHp>
      <Garbage>4</Garbage>
    </Cost>
    <EventId>2</EventId>
    <EventType>Good</EventType>
  </Event>
</ArrayOfEvent>
基本序列化程序方法

private void serializeList()
{
    XmlSerializer ser = new XmlSerializer(typeof(List<Event>));
    List<Event> list = new List<Event>();
    list.Add(new Event { EventId = 1, Description = "abc", EventType = EventType.Good, Cost = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 }, Reward = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 } });
    list.Add(new Event { EventId = 2, Description = "def", EventType = EventType.Good, Cost = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 }, Reward = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 } });
    list.Add(new Event { EventId = 3, Description = "ghi", EventType = EventType.Good, Cost = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 }, Reward = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 } });
    StreamWriter sw = new StreamWriter("Assets/TextResources/test.xml");
    ser.Serialize(sw, list);
    sw.Close();
}

感谢您的反馈,虽然这是一个问题,但问题并不是很大
[Serializable, XmlRoot("Event")]
public class Event
{
    [XmlElement("Description")]
    public string Description { get; set; }

    [XmlElement("Reward")]
    public Resources Reward { get; set; }

    [XmlElement("Cost")]
    public Resources Cost { get; set; }

    [XmlElement("EventId")]
    public int EventId { get; set; }

    [XmlElement("EventType")]
    public EventType EventType { get; set; }
    [XmlIgnore]
    public string MarkUp { get; set; }
}


[Serializable, XmlRoot("Resources")]
public class Resources
{
    //Each prop can be extended to food being a Food object with expiry, etc
    [XmlElement("Food")]
    public int Food { get; set; } // 0 to cap
    [XmlElement("Happiness")]
    public int Happiness { get; set; } // 0 to 100
    [XmlElement("Energy")]
    public int Energy { get; set; } //0 to cap
    [XmlElement("ShipHp")]
    public int ShipHp { get; set; }// cap to 0
    [XmlElement("Garbage")]
    public int Garbage { get; set; } // 0 to cap
}

[XmlType("EventType")]
public enum EventType
{
    [XmlEnum("Good")]
    Good = 0,
    [XmlEnum("Bad")]
    Bad,
    [XmlEnum("Neutral")]
    Neutral
}


public class EventHandler : MonoBehaviour
{

    List<Event> Events = new List<Event>();

    // Use this for initialization, called on script enabling
    void Start()
    {
        try
        {
            var serializer = new XmlSerializer(typeof(List<Event>));

            string xml = File.ReadAllText("Assets/TextResources/Events.xml");
            xml = XDocument.Parse(xml).ToString(SaveOptions.DisableFormatting);

            using (var stringReader = new StringReader(xml))
            {
                using (var reader = XmlReader.Create(stringReader))
                {
                    var result = (List<Event>)serializer.Deserialize(reader);
                    Events = result;
                }
            }
        }
        catch (Exception ex)
        {
            Debug.Log(ex);
        }
    }
}
private void serializeList()
{
    XmlSerializer ser = new XmlSerializer(typeof(List<Event>));
    List<Event> list = new List<Event>();
    list.Add(new Event { EventId = 1, Description = "abc", EventType = EventType.Good, Cost = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 }, Reward = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 } });
    list.Add(new Event { EventId = 2, Description = "def", EventType = EventType.Good, Cost = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 }, Reward = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 } });
    list.Add(new Event { EventId = 3, Description = "ghi", EventType = EventType.Good, Cost = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 }, Reward = new Resources { Food = 0, Energy = 1, Happiness = 2, ShipHp = 3, Garbage = 4 } });
    StreamWriter sw = new StreamWriter("Assets/TextResources/test.xml");
    ser.Serialize(sw, list);
    sw.Close();
}