如何在c#中编辑json文件?

时间:2016-04-22 04:30:58

标签: c# json

我正在进行文字冒险,每当玩家输入"拿起铁剑"或者其他什么,我需要能够把JSON阵列中的铁剑从它所保留的房间里取出来。

{
Rooms: [
    {
        id: "PizzaShop1",
        name: "Pizza Shop",
        description: "in a nice warm pizza shop that smells of garlic.",
        items: [
            {
                id: "HawaiianPizza1",
                name: "Hawaiian Pizza",
                description: "a pizza topped with ham and pineapple",
                strengthMod: 0,
                toughnessMod: 0
            },
            {
                id: "MeatloversPizza1",
                name: "Meatlovers Pizza",
                description: "a pizza topped with lots of meat",
                strengthMod: 0,
                toughnessMod: 0
            }
        ],
        entities: [
            {
                name: "Pizza Chef",
                description: "an italian man",
                friendly: true
            },
            {
                name: "Mouse",
                description: "a pesky mouse",
                friendly: false
            }
        ],
        northExit: "",
        southExit: "Road1",
        eastExit: "",
        westExit: ""
    },     
    {
        id: "Road1",
        name: "Road",
        description: "on a town road",
        items: [
            {
                id: "IronSword1",
                name: "Iron Sword",
                description: "a battered but usable sword",
                strengthMod: 2,
                toughnessMod: 0
            }
        ],
        entities: [],
        northExit: "PizzaShop1",
        southExit: "",
        eastExit: "",
        westExit: ""
    }
]
}

这是我的c#代码:

                else if (s.Contains(" pick up "))
            {
                String newJson = "";
                s = s.Replace(" the ", " ");
                s = s.Replace(" pick ", " ");
                s = s.Replace(" up ", " ");
                String[] Words = s.Split(' ');
                foreach (String word in Words)
                {
                    if (word != Words[1])
                    {
                        Words[1] = Words[1] + " " + word;
                        Words[1] = Words[1].Replace("  ", " ");
                        Words[1] = Words[1].Trim();
                    }
                }
                using (StreamReader sr = new StreamReader("TAPResources/map.json"))
                {
                    String json = sr.ReadToEnd();
                    dynamic array = JsonConvert.DeserializeObject(json);
                    foreach (var rooms in array["Rooms"])
                    {
                        foreach (var item in rooms["items"])
                        {
                            String itm = (String)item["name"];
                            PrintMessage("Words: " + Words[1]);
                            PrintMessage("Item Name: " + itm.ToLower());
                            if (Words[1] == itm.ToLower())
                            {
                                rooms["items"].Remove(item);
                            }
                        }
                    }
                    newJson = (String)JsonConvert.SerializeObject(array);
                }
                File.WriteAllText("TAPResources/map.json", newJson);
            }

该行:

rooms["items"].Remove(item);

给出错误,因为我无法在循环内编辑数组。通常我会通过将值添加到另一个数组来解决这个问题,然后遍历该数组以从初始数组中删除,但我不知道如何为该变量类型创建数组。

2 个答案:

答案 0 :(得分:1)

您可能希望添加代表游戏,房间和项目的类,然后在游戏进行时将它们保存在内存中。当他们保存游戏时,您可以将其序列化为JSON。使用对象比尝试遍历整个文档室和每个项目以查找一个项目并将其删除更容易。

我会根据您的Json文档建议以下类:

public class Item
{
    public string id { get; set; }
    public string name { get; set; }
    public string description { get; set; }
    public int strengthMod { get; set; }
    public int toughnessMod { get; set; }
}

public class Room
{
    public string id { get; set; }
    public string name { get; set; }
    public string description { get; set; }
    public List<Item> items { get; set; }
    public List<object> entities { get; set; }
    public string northExit { get; set; }
    public string southExit { get; set; }
    public string eastExit { get; set; }
    public string westExit { get; set; }
}

public class Game
{
    public List<Room> Rooms { get; set; }
}

然后你可以将你的JSON反序列化为这样的Game对象:

var game = JsonConvert.DeserializeObject<Game>(json);

然后,如果你想从&#34; Road1&#34;它比循环动态对象简洁得多:

//Find room by id and remove item by id
game.Rooms.Single(room => room.id == "Road1")
    .items.RemoveAll(item => item.id == "Iron Sword");

//Turn the game object back into a Json string
var json = JsonConvert.SerializeObject(game);

//now write json string back to storage...

这为您在运行时提供了更大的灵活性。例如,即时添加新房间变得非常容易:

var room = new Room
        {
            id = "new room",
            name = "very cool room",
            description = "A very cool room that was added on the fly",
            items = new List<Item> 
                        { 
                          new Item 
                               { 
                                 id = "another sword", 
                                 description = "Another battered sword"
                                 //etc...
                                } 
                          }
            //etc...
        }

game.Rooms.Add(room);

希望这有帮助。

答案 1 :(得分:1)

好的,所以我们走了,理想情况下建议使用定义良好的对象(类)使用动态对象的情况是一个较慢的处理,任何如何:

dynamic array = GetRooms();

    foreach (var rooms in array["Rooms"])
    {
        List<object> list = new List<object>();
        foreach (var item in rooms["items"])
        {
            string itm = (string) item["name"];
            if (!"hawaiian pizza".Equals(itm.ToLower()))
            {
                list.Add(item);
            }
        }
        //u can use this 
        //from rooms in array["Rooms"] select rooms where (true something)
        //or what I did case I'm lazy
        //Newtonsoft.Json.Linq.JToken transfor or you can use linq to dow whatever 
        rooms["items"] = JsonConvert.DeserializeObject<JToken>(JsonConvert.SerializeObject(list.ToArray()));
    }
    Console.Write(JsonConvert.SerializeObject(array));