如何对隐藏在其他元素中的字典进行XML反序列化



实际代码和xml文件

程序代码

class Program
{
static void Main(string[] args)
{
string path = AppDomain.CurrentDomain.BaseDirectory + "file.xml";
//string path2 = @"F:fd.xml";
FileStream fs = new FileStream(path, FileMode.Open);
XmlReader reader = XmlReader.Create(fs);
SaveGame sav = new XmlSerializer(typeof(SaveGame)).Deserialize(reader) as SaveGame;
Console.WriteLine(sav.player.friendshipData[0].key);
Console.WriteLine(sav.player.friendshipData[0].value.Points);
fs.Close();
Console.ReadKey();
}
}
public class SaveGame
{
public Player player { get; set; }
}
public class Player
{
public item[] friendshipData { get; set; }
}
public class item
{
public string key { get; set; }
public Friendship value { get; set; }
}
public class Friendship
{
public int Points {get;set;}
}
}

要使用的XML文件:

<SaveGame>
<player>
<friendshipData>
<item>
<key>
<string>Name1</string>
</key>
<value>
<Friendship>
<Points>324</Points>
</Friendship>
</value>
</item>
<item>
<key>
<string>Name2</string>
</key>
<value>
<Friendship>
<Points>98</Points>
</Friendship>
</value>
</item>
</friendshipData>
</player>
</SaveGame>

我尝试了其他帖子,但这不起作用,因为所有readen值都为null。

请问,如何反序列化此文档?请解释一下。

如果我将{get;set;}设置为变量,它将不会读取下一项,如果我设置{get;},它将读取每个项,但每个项都有空值。

以防万一,由于某些原因,我无法编辑XML文件。XML文件正常。

您的数据结构并不适合您的xml。如果您有一个简单的数据类型,如intstring,则可以将直接序列化和反序列化到xml节点中。如果您有一些更复杂的数据结构,如Firnedship-节点,则需要一个嵌套节点。

话虽如此,您的数据结构应该类似于以下内容:

public class SaveGame
{
public Player player { get; set; }
}
public class Player
{
public item[] friendshipData { get; set; }
}
public class item
{
public Key key { get; set; }
public Friendship value { get; set; }
}
// add this class with a single string-field
public class Key
{
public string @string { get; set;  }
}
public class Friendship
{
public int Points { get; set; }
}

顺便考虑一下以下命名约定,它为类和这些类的成员提供PascaleCase名称,例如FriendshipDataItemKey。然而,这假设您在xml中有一些从这些名称到您的名称的映射。这可以通过使用XmlElementAttribute:来完成

public class Player
{
[XmlElement("friendshipData ")] // see here how to change the name within the xml
public item[] FriendshipData { get; set; }
}

由于您只需要Xml中的两个值,因此我不会使用序列化。你只需一个linq指令就可以得到一本字典。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication51
{
class Program
{
const string FILENAME = @"c:temptest.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Dictionary<string, int> players = doc.Descendants("item")
.GroupBy(x => (string)x.Descendants("string").FirstOrDefault(), y => (int)y.Descendants("Points").FirstOrDefault())
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}

}