获取JSON对象的绝对路径

时间:2019-10-23 12:29:11

标签: c# json json.net

我有一个JSON对象:

{
  ""settings"": {
    ""general"": {
      ""database"": { ""type"": ""PostgreSql"" }
    }
  }
}

我的JSON对象的绝对路径如下:settings/general/database/type

我尝试使用此question的第一个解决方案来获取所有密钥:

IList<string> keys = parent.Properties().Select(p => p.Name).ToList();

这对我不起作用。 keys列表仅包含第一个键settings,而没有其他键。

有一个path属性,它显示您所在节点的路径,但不显示JSON对象的完整路径。

enter image description here

如何获得示例中的绝对路径?

3 个答案:

答案 0 :(得分:3)

在您的问题中,您正在询问如何获取“我的JSON对象”的路径,但示例JSON实际上包含嵌套的四个对象。 (每个对象在JSON中均以{开头,并以}结尾。)因此,路径将有所不同,具体取决于所引用的JSON对象。看起来您当前正在引用要查询的最外层对象,以获取其属性的名称。但是,正如您所看到的,这不会给您后代属性。您需要的是从 innermost 属性中获取Path

所以我认为我们可以将您的问题归结为:

  

给出一些JSON,如何获取层次结构中最深值(即叶节点)的完整路径?

您可以通过以下LINQ-to-JSON查询来做到这一点:

var obj = JObject.Parse(json);

var paths = obj.DescendantsAndSelf()
               .OfType<JProperty>()
               .Where(jp => jp.Value is JValue)
               .Select(jp => jp.Path)
               .ToList();

如果只想要第一个,则将.ToList()替换为.FirstOrDefault()

请注意,路径将以点作为定界符返回。如果您希望使用斜杠,请在.Replace('.', '/')方法调用内将jp.Path添加到Select()

此处的工作演示:https://dotnetfiddle.net/lFXtEE

答案 1 :(得分:1)

您的父对象只有一个键,即“设置”。它的值是一个json对象。该对象只有一个键,即“通用”键。它的值是一个json对象。该对象只有一个键,即“数据库”。它的值是一个json对象。您正在使用嵌套对象,因此您必须具体说明“需要所有对象的所有键”。

答案 2 :(得分:1)

您引用的SO答案不起作用,因为它只为您提供根对象中的所有键作为字符串列表。

您想要的是一种递归的方式来获取所有“键”(JProperty.Name)。 如果您将JPropertyName = "type"一起使用,我们将其称为JProperty typeProp;。然后typeProp.Parent将为您提供包含JContainer的{​​{1}},而""type"" : ""PostgreSql""将为您提供一个typeProp.Parent.Parent的{​​{1}}。

所以这样的事情可能会有所帮助(当心,未经测试):

JProperty

这样会在结尾处留下一个额外的斜线:

Name = "database"

您可以使用以下方法将其删除:

JToken current = typeProp;
string path = "";

while (current != null)
{
    path = current.Name + "/" + path;
    if(current.Parent != null) current = current.Parent.Parent;
}
相关问题