首页 > 解决方案 > 如何在 Unity 中解析以特殊字符开头的嵌套 JSON 对象?

问题描述

我正在尝试从 MongoDB 获取这些信息,它给了我这个 JSON 来处理:

{
    \"values\":
        [ 
            { \"_id\" : { \"$oid\" : \"5ccf1bc55d0e652b8a6c9153\"} , \"Id\" : 5 ,\"Name\" : \" palups\"} , 
            { \"_id\" : { \"$oid\" : \"5ccf24e91f6e4f29b5ede29b\"} , \"Id\" : 2 ,\"Name\" : \"Maria\"} , 
            { \"_id\" : { \"$oid\" : \"5ccf25071f6e4f29b5ede2c5\"} , \"Id\" : 3 ,\"Name\" : \"marcela\"}
        ]
}

问题在于嵌套对象 $oid。我设法获得了 ID 和名称,但没有获得嵌套对象。

这是我尝试过的:

[System.Serializable]
public class ScoreData {
    public List<Values> values = new List<Values>();
}

[System.Serializable]
public class Values
{
    public _id oid;
    public int Id;
    public string Name;
}

[System.Serializable]
public class _id
{
    public string m_oid;
}

上面的部分是我创建的类,下面的代码是提供给我的函数,加上我的补充使它按我想要的方式工作:

IEnumerator getProductsInDB(){
    UnityWebRequest unityWebRequest = UnityWebRequest.Get (baseURL+databaseName+"/collections/"+collectionName+"?apiKey=" + apiKey);
    yield return unityWebRequest.Send();

    if(unityWebRequest.isNetworkError || unityWebRequest.isHttpError) {
        Debug.Log(unityWebRequest.error);
    }
    else {
        //Debug.Log (unityWebRequest.downloadHandler.text);
        jsonString = unityWebRequest.downloadHandler.text;

        string JSONToParse = "{\"values\":" + jsonString + "}"; //estava faltando no json ???

        ScoreData loadedScoreData = JsonUtility.FromJson<ScoreData>(JSONToParse);

        for (int i = 0; i <= loadedScoreData.values.Count; i++)
        {
            Debug.Log("score: " + loadedScoreData.values[i].oid.m_oid);
            Debug.Log("score: " + loadedScoreData.values[i].Id);
            Debug.Log("name: " + loadedScoreData.values[i].Name);
            Debug.Log("****************************************");
        }
    }
}

这就是我在 Unity 控制台上得到的:

https://imgur.com/a/gQ2ZeZR

(如您所见,第一行是空的)。

分数:

UnityEngine.Debug:日志(对象)

得分:999

UnityEngine.Debug:日志(对象)

姓名:马塞拉

UnityEngine.Debug:日志(对象)

那么,如何解析嵌套值或我做错了什么?

标签: c#jsonunity3d

解决方案


因为JsonUtility您的类中的字段名称必须与您的 JSON 字符串中的字段名称匹配。否则,“缺失”字段将仅具有其默认值(在您的情况下"")。

因此,从您的 JSON 示例中的命名来看

  • 在课堂Values上它应该是

      public _id _id;
    
  • 在课堂_id上它必须

      public string $oid;
    

但是后者不是c# 中的有效标识符名称

  • 标识符必须以字母或_. 开头。
  • 标识符可能包含 Unicode 字母字符、十进制数字字符、Unicode 连接字符、Unicode 组合字符或 Unicode 格式字符。有关 Unicode 类别的更多信息,请参阅 Unicode 类别数据库。您可以通过在标识符上使用 @ 前缀来声明与 C# 关键字匹配的标识符。@ 不是标识符名称的一部分。例如,@if 声明了一个名为 if 的标识符。这些逐字标识符主要用于与以其他语言声明的标识符的互操作性。

前缀$不符合这些规则。

因此,如果您无法更改 JSON,我担心JsonUtility在这种情况下对您没有帮助,您应该寻找另一个 Json 解析器。


例如,您可以使用SimpleJson以便在Values之后为每个实例检索此特定字段并将其传入。


反正

最简单的解决方案是在解析它之前删除或替换该特殊字符,例如

string JSONToParse = ("{\"values\":" + jsonString + "}").Replace('$', '_');

而是改变

[Serializeable]
public class _id
{
    public string _oid;
} 

也正如 Rufo 爵士评论的那样,你真的确定你必须这样做吗?

string JSONToParse = ("{\"values\":" + jsonString + "}");

? 在您的问题中,您是说您已经收到了 JSON,包括{ }values字段...


推荐阅读