【问题标题】:Get absolute path of JSON object获取 JSON 对象的绝对路径
【发布时间】:2019-10-23 12:29:11
【问题描述】:

我有一个 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 对象的完整路径。

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

【问题讨论】:

标签: c# json json.net


【解决方案1】:

在您的问题中,您询问如何获取“我的 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()

请注意,返回的路径将以点作为分隔符。如果您更喜欢斜线,请在 Select() 方法调用中将 .Replace('.', '/') 添加到 jp.Path

这里的工作演示:https://dotnetfiddle.net/lFXtEE

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我没有注意到这一点。确切地说,我正在尝试获取嵌套对象的每个键。就像你说的我想要父对象的关键“设置”。它的值是一个 json 对象。该对象只有一个键,即“通用”。我也想要这个。最后,我将按以下顺序获得键:设置、常规、数据库、类型
    【解决方案3】:

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

    您想要的是一种获取所有“密钥”(JProperty.Name)的递归方式。 如果您有JPropertyName = "type",我们就叫它JProperty typeProp;。然后typeProp.Parent 将为您提供包含""type"" : ""PostgreSql""JContainertypeProp.Parent.Parent 将为您提供JPropertyName = "database"

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

    JToken current = typeProp;
    string path = "";
    
    while (current != null)
    {
        path = current.Name + "/" + path;
        if(current.Parent != null) current = current.Parent.Parent;
    }
    

    这会在末尾留下一个额外的斜线,如下所示:

    settings/general/database/type/
    

    你可以删除:

    char[] charsToTrim = {'/'};
    path.trimEnd(charsToTrim)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-14
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 2012-09-03
      • 1970-01-01
      • 2021-05-31
      • 2012-08-27
      相关资源
      最近更新 更多