JsonPath with JsonTextReader: Token at a Time



我在加载令牌时遇到 JsonPath 工作方式不同的问题(.一次使用 JsonTextReader 加载),而不是使用 ReadFrom 加载整个 JSON。 下面是一个示例: JSON: path="[*].person" Method=SelectTokens(path)

[
{
"person": {
"personid": 123456
}
},
{
"person": {
"personid": 798
}
}
]

使用 .读取自,它将返回正确的 2 个元素。 如果我使用 .加载,但它将返回 0 个元素。但是,如果我将路径更改为">",.读取源返回 0 个元素,而 .Load 返回 2 个元素。

作为修复,我可以更改路径,以便它删除第一个".",即路径 = 子字符串(path.index(".")+1);但是,这感觉更像是一种黑客攻击,而不是适当的修复。 当然,我还需要确保 JSON 是一个数组,但在大多数情况下,它会是数组。

所以最后,我正在尝试学习如何在一次加载令牌时将 JSON 路径与数组一起使用。有什么建议吗?

完整代码

完整的 JSON

在你链接到的代码中发生的情况是,它读取令牌,直到遇到一个对象,然后从这个对象加载一个JToken,它读到这个对象的末尾。 因此,您最终得到的是根数组中每个项目的JToken。然后,您可以为每个JToken呼叫:

token.SelectTokens("person").OfType<JObject>()

因为您知道该属性包含一个对象。

这相当于在整个解析的 JSON 上执行"[*].person"JsonPath。

我希望我正确理解了你的问题。如果没有,请告诉我=)

更新:

根据您的评论,我了解您的追求。您可以做的是创建如下方法:

public IEnumerable<JToken> GetTokensByPath(TextReader tr, string path)
{
// do our best to convert the path to a RegEx
var regex = new Regex(path.Replace("[*]", @"[[0-9]*]"));
using (var reader = new JsonTextReader(tr))
{
while (reader.Read())
{
if (regex.IsMatch(reader.Path))
yield return JToken.Load(reader);
}
}
}

我正在根据 JSON 路径输入匹配路径,但我们需要尝试处理所有各种 JSON 路径语法,目前我只支持*. 当您有一个大型文件时,此方法将很有用,并且具有深度 JSON 路径选择器,如果您枚举缓慢,您将保持流打开更长时间,但您的峰值内存使用量要低得多。

我希望这有所帮助。

相关内容

  • 没有找到相关文章

最新更新