[英]Deserialize xml into list of objects
我正在嘗試將一些xml反序列化為對象列表。
我遇到麻煩的地方是Event
對象中的輔助對象Resources
沒有填充值。 對於更多的背景知識,這是一個統一的項目,我正在反序列化可能發生的隨機事件的列表。
以下是我正在測試的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 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 string EventType { get; set; }
}
[XmlType("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
}
這是我的反序列化代碼:
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
的值,但是Reward
和Cost
資源對象中卻沒有填充這些值,到目前為止,我不知所措。 為了獲得加分,我還努力尋找一種方法,以簡單地除去解析字符串后得到的所有無效空間。 (即Good更改為“ \\ n \\ r Good”)。
好。 因此,我找到了解決問題的方法,我對這方面都不是專家,因此,如果有任何更正經驗的人想要添加改進以改進代碼,我將很樂意進行更改。
首先,我的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>
所以首先要注意的是,我序列化了事件對象列表,這些對象是<ArrayOfEvent>
標記和生成的xml名稱空間屬性。 從那開始。 這也意味着我必須從EventData
類更改為List<Event>
,這在任何方面都更加方便。 從Event
和Resources
類中,我將[Serializable, XmlRoot()]
標記添加到了它們的類中。 要注意的另一件事是,我將EventType
從字符串交換為枚舉,該枚舉的代碼也將在下面提供。這些修補程序還修復了我從xml純文本獲取到XmlReader的格式問題,我將共享完整的以下代碼供將來的讀者使用:
[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();
}
您的XML無效。 您的第一個Resources標簽永遠不會關閉。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.