我有一个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对象的完整路径。
如何获得示例中的绝对路径?
答案 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)。
如果您将JProperty
与Name = "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;
}