unity3d 如何在c#中访问和存储json文件中的特定对象

vtwuwzda  于 2022-11-15  发布在  C#
关注(0)|答案(4)|浏览(186)

我正在尝试用unity3D制作一个多主题的儿童问答游戏,问题和答案都存储在一个json文件中。现在我想创建一个名为“science”和“maths”的对象,并将它们各自的问题存储在其中。当我想访问science时,我可以循环查找,并将science问题存储在字符串中,而不是阅读整个json文件。
这是我json文件。

Science ={
    "CourseName":"Science",
    "No_Of_Ques":4,
    "Ques_Data":[
                  { "Quesion":"which is the biggest planet in the solar system?",
                    "Answer":"jupiter",
                    "options":["mars","earth","venus","jupiter"] 
                  },

                  { "Quesion":"How many planets are there in solar system?",
                    "Answer":"Eight",
                    "options":["Seven","Nine","Five","Eight"] 
                  },

                  { "Quesion":"which is the closest planet to the sun?",
                    "Answer":"mercury",
                    "options":["mars","saturn","venus","mercury"] 
                  },

                  { "Quesion":"How many moons does jupiter have?",
                    "Answer":"12",
                    "options":["5","13","9","12"] 
                  }
                ]   
}

这就是我到目前为止的方法

path = Application.dataPath + "/QnA.json";
    string json = File.ReadAllText(path);
    Course c1 = JsonUtility.FromJson<Course>(json);

    return c1;

课程和所需的可序列化类:

[Serializable] public class Course 
{ 
    public string CourseName;
    public string No_Of_Ques;
    public QnA[] Ques_Data; 
}

[Serializable]
public class QnA 
{ 
    public string Quesion;
    public string Answer;
    public string[] options;
}

我已经尝试了这么多的东西,如反序列化和Jobject资产,但他们似乎都不工作,每一个实现,我发现在互联网上有相同的文件作为c#代码的json数据,但我不能这样做,因为我的json包含数百行数据。请帮助我一点。

wnavrhmk

wnavrhmk1#

创建一个课程类,在其中为所有json键创建getter和setter函数,例如:
如果您json文件如下所示:

[
  {
    "CourseName": "Science",
    "No_Of_Ques": 1,
    ...
  },
  {
    "CourseName": "Math",
    "No_Of_Ques": 1,
    ...
  }
]

则课程类应为:

public class Course
    {
        public string CourseName { get; set; }
        public int No_Of_Ques { get; set; }
    }

在你的主类或任何地方,你可以访问你选择的课程,在这里我只使用0索引的一个json,你也可以循环通过整个json,并找到你想要的课程。

  • StreamReader读取文件
  • 将其转换为json
  • 根据您的课程反序列化json
  • 控制它
using (StreamReader r = new StreamReader("../../../js.json"))
    {
        string json = r.ReadToEnd();
        List<Course> ro = JsonSerializer.Deserialize<List<Course>>(json);
        Console.WriteLine(ro[0].CourseName);
    }

我在我的mainClass文件所在的同一个目录中添加了json文件,因为StreamReader需要一个绝对路径,因此我为我的json文件使用了一个绝对路径。

using (StreamReader r = new StreamReader("../../../js.json"))

需要程式库

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;

注意:我创建了一个控制台应用程序,不确定您的应用程序类型

ma8fv8wu

ma8fv8wu2#

如果你想在你的文件中存储多个课程,你需要将它们存储为json数组(就像你处理问题一样):

[
   {
      "CourseName":"Science",
      "No_Of_Ques":1,
      "Ques_Data":[
         {
            "Question":"which is the biggest planet in the solar system?",
            "Answer":"jupiter",
            "options":[
               "mars",
               "jupiter"
            ]
         }
      ]
   },
   {
      "CourseName":"Math",
      "No_Of_Ques":1,
      "Ques_Data":[
         {
            "Question":"2 + 2",
            "Answer":"4",
            "options":[
               "4",
               "0"
            ]
         }
      ]
   }
]

然后可以使用next结构(例如)对它们进行反序列化:

public class Course
{
    [JsonProperty("CourseName")]
    public string CourseName { get; set; }
    [JsonProperty("No_Of_Ques")]
    public long NoOfQues { get; set; }
    [JsonProperty("Ques_Data")]
    public QuesDatum[] QuesData { get; set; }
}

public class QuesDatum
{
    [JsonProperty("Question")]
    public string Question{ get; set; }

    [JsonProperty("Answer")]
    public string Answer { get; set; }

    [JsonProperty("options")]
    public string[] Options { get; set; }
}

var courses = JsonConvert.DeserializeObject<List<Course>>(jsonString);
var course = courses.Where(...).FirstOrDefault();

或者尝试使用json path

var course = JToken.Parse(jsonString)
    .SelectToken("$[?(@.CourseName == 'Math')]")
    .ToObject<Course>();

对于jsonString,您可以通过任何方式获得它,例如从文件中阅读。
附言
存在排印错误“问题”-〉“问题”

czfnxgou

czfnxgou3#

要序列化和反序列化对象,必须创建一个可以是[Serializable]的C#类(在您的情况下应该是Course类)。
首先,您的Json应该是有效的Json,它是有效的,您可以通过here验证它。
要进行序列化和反序列化,您可以在一定程度上使用JsonUtility,因为它不会反序列化锯齿数组、复杂对象等。我建议使用第三方软件(如Newtonsoft)或为way实现您自己的序列化/反序列化方法。

编辑:

您的JSON文件应该没有“Science=”部分,应该如下所示:

{
    "CourseName":"Science",
    "No_Of_Ques":4,
    "Ques_Data":[
                  { "Quesion":"which is the biggest planet in the solar system?",
                    "Answer":"jupiter",
                    "options":["mars","earth","venus","jupiter"] 
                  },

                  { "Quesion":"How many planets are there in solar system?",
                    "Answer":"Eight",
                    "options":["Seven","Nine","Five","Eight"] 
                  },

                  { "Quesion":"which is the closest planet to the sun?",
                    "Answer":"mercury",
                    "options":["mars","saturn","venus","mercury"] 
                  },

                  { "Quesion":"How many moons does jupiter have?",
                    "Answer":"12",
                    "options":["5","13","9","12"] 
                  }
                ]   
}

编辑:对于你的评论,我认为你对如何处理文件和变量之间的关系有误解。
您希望每种类型的课程都有一个文件(或者至少看起来是这样),因此在本例中,上面的文本将是您的Science.json文件。
当您存储该信息时,您将执行类似的操作:

path = Application.dataPath + "/QnA.json";
    string json = File.ReadAllText(path);
    Course scienceCourse = JsonUtility.FromJson<Course>(json); //notice the name of the variable!

因此,正如您可以看到的变量名称,您将读取每个课程的每个单个JSON。
另一种方法是将所有课程存储在同一个Json文件中,然后将它们作为课程数组-〉Course[] allCourses

bvhaajcl

bvhaajcl4#

使用Science={...}来定义对象会让您对对象定义感到困惑。它不是Science对象,而是Course对象。
应该更像

{
    "Courses" :
    [
        {
            "CourseName" : "Science",
            ...
        },
        {
            "CourseName" : "Maths",
            ...
        }
    ]
}`.

Package :

"Quiz" :
{
    "Courses" :
    [
        {
            "CourseName" : "Science",
            ...
        },
        {
            "CourseName" : "Maths",
            ...
        }
    ]
}

以及使用了

[Serializable]
public class Quiz
{
    public Course[] courses;
}

将其作为C#对象保存。
在这里,您可以通过quiz.Courses[0].Questions[17]访问您的课程,或者在Quiz类中编写帮助器方法,以便通过quiz.GetCourse(CourseCategory.Science).Questions[8]之类的枚举调用课程。
我还建议使用Questions而不是Question_Data,这样对对象更友好,在语义上也更有帮助。
作为一个额外的建议,您可以考虑根据课程发送一个Course对象,而不是将所有的测验都转储到一个JSON中,使用http://myquizserver.com/quiz.php?course=science之类的查询请求。由于您提到了数百行JSON,您还可以考虑逐个问题地获取数据。

相关问题