Linq-to-JSON SelectToken 方法混淆和备选方案
Linq-to-JSON SelectToken Method Confusion and Alternatives
我希望我可以在不提供代码示例的情况下提出这个问题,因为它更多的是关于缺少文档和潜在的替代方案 methods/commands。
在我现有的 Linq-to-JSON 代码中,我有这个片段:
var firstOrDefault = parent.AncestorsAndSelf()
.Select(p => p.SelectToken("COMPANY"))
.FirstOrDefault(k => k != null);
此代码位于一个更大的 Linq 查询中,该查询遍历所有 JArray 和从根 JSON 对象派生的所有 JObject 对象。
我的问题与 p.SelectToken("COMPANY")
有关。这似乎是在查看父级 JSON 的祖先树,并获取它看到的名称为 "COMPANY" 的第一个或默认标记的 VALUE。这正是我需要它做的。但我现在有两个额外的要求:
- 我知道任何名为 "COMPANY" 的标记总是会映射到一个字符串值。
- 我需要获取与 COMPANY 一起使用的兄弟字符串值 JProperty 对象。
因此,我的 JSON 片段可能如下所示:
{
"COMPANY":"Microsoft",
"LOCATION":"Seattle",
"PHONE":"800-555-1212"
"METADATA" :
{
"AA":"AA",
"BB":"BB"
}
}
在此示例中,我想使用 p.SelectToken
查找包含 "COMPANY" 条目的第一个祖先标记——但随后我需要构建一个包含所有同级 JProperty 值的列表,以便 List 包含这些 JProperty 元素:
"COMPANY":"Microsoft"
"LOCATION":"Seattle"
"PHONE":"800-555-1212"
在 Select 的 lambda 表达式中返回 p.SelectToken。我对 Linq 或各种 JSON.NET 方法知之甚少,无法知道使用 SelectToken 以外的哪种方法来 select 同一对象中的所有同级属性作为 selected 标记。我尝试使用 .Where
和 (jt => (jt.Type == JTokenType.JProperty)
的 lambda,然后使用 .Select
和 (p => p.Name == "COMPANY")
的 lambda,但这总是产生 0 个结果。我只是迷路了。我唯一能想到的是,也许解决方案需要的不仅仅是对 lambda 表达式的更新,例如带有附加变量的完整函数等。
此外,我在 JSON.NET 找不到任何关于 SelectToken 的好文档。我只看到一个简单的例子和一个关于它做什么的句子。如果还有其他资源可以学习此类 JSON.NET Linq 方法,请分享。
我相信这应该可以满足您的要求:
var firstOrDefault = parent
// Walk up the hierarchy
.AncestorsAndSelf()
// Find an object of type JObject
.OfType<JObject>()
// That has a COMPANY property
.Where(o => o["COMPANY"] != null)
// Make a new JObject with the string properties of that JObject
.Select(o => new JObject(o.Properties().Where(p => p.Value.Type == JTokenType.String)))
// And return the first (lowest) one.
.FirstOrDefault();
我希望我可以在不提供代码示例的情况下提出这个问题,因为它更多的是关于缺少文档和潜在的替代方案 methods/commands。
在我现有的 Linq-to-JSON 代码中,我有这个片段:
var firstOrDefault = parent.AncestorsAndSelf()
.Select(p => p.SelectToken("COMPANY"))
.FirstOrDefault(k => k != null);
此代码位于一个更大的 Linq 查询中,该查询遍历所有 JArray 和从根 JSON 对象派生的所有 JObject 对象。
我的问题与 p.SelectToken("COMPANY")
有关。这似乎是在查看父级 JSON 的祖先树,并获取它看到的名称为 "COMPANY" 的第一个或默认标记的 VALUE。这正是我需要它做的。但我现在有两个额外的要求:
- 我知道任何名为 "COMPANY" 的标记总是会映射到一个字符串值。
- 我需要获取与 COMPANY 一起使用的兄弟字符串值 JProperty 对象。
因此,我的 JSON 片段可能如下所示:
{
"COMPANY":"Microsoft",
"LOCATION":"Seattle",
"PHONE":"800-555-1212"
"METADATA" :
{
"AA":"AA",
"BB":"BB"
}
}
在此示例中,我想使用 p.SelectToken
查找包含 "COMPANY" 条目的第一个祖先标记——但随后我需要构建一个包含所有同级 JProperty 值的列表,以便 List 包含这些 JProperty 元素:
"COMPANY":"Microsoft"
"LOCATION":"Seattle"
"PHONE":"800-555-1212"
在 Select 的 lambda 表达式中返回 p.SelectToken。我对 Linq 或各种 JSON.NET 方法知之甚少,无法知道使用 SelectToken 以外的哪种方法来 select 同一对象中的所有同级属性作为 selected 标记。我尝试使用 .Where
和 (jt => (jt.Type == JTokenType.JProperty)
的 lambda,然后使用 .Select
和 (p => p.Name == "COMPANY")
的 lambda,但这总是产生 0 个结果。我只是迷路了。我唯一能想到的是,也许解决方案需要的不仅仅是对 lambda 表达式的更新,例如带有附加变量的完整函数等。
此外,我在 JSON.NET 找不到任何关于 SelectToken 的好文档。我只看到一个简单的例子和一个关于它做什么的句子。如果还有其他资源可以学习此类 JSON.NET Linq 方法,请分享。
我相信这应该可以满足您的要求:
var firstOrDefault = parent
// Walk up the hierarchy
.AncestorsAndSelf()
// Find an object of type JObject
.OfType<JObject>()
// That has a COMPANY property
.Where(o => o["COMPANY"] != null)
// Make a new JObject with the string properties of that JObject
.Select(o => new JObject(o.Properties().Where(p => p.Value.Type == JTokenType.String)))
// And return the first (lowest) one.
.FirstOrDefault();