通过c#中的动态过滤器查询过滤复杂的JSON

问题描述 投票:1回答:1

[我正在尝试在我的一个项目中创建JSON过滤,此处JSON将是动态的,因此无法创建模型,过滤器将来自用户,我的示例JSON是

[
  {
    "id": 101,
    "field1": "f1",
    "field2": "f2",
    "InnerArray": [
      {
        "id": 201,
        "innerField1": "f1",
        "innerField2": "f2"
      },
      {
        "id": 202,
        "innerField1": "f1",
        "innerField2": "f2"
      }
    ]
  },
  {
    "id": 102,
    "field1": "ff1",
    "field2": "ff2",
    "InnerArray": [
      {
        "id": 301,
        "innerField1": "f1",
        "innerField2": "f2"
      },
      {
        "id": 302,
        "innerField1": "f1",
        "innerField2": "f2"
      }
    ]
  }
]

我正在尝试通过SelectToken()对此进行过滤,除了内部数组之外,它将正常工作例如,如果查询是

string filter = "$.[?(@.id==101)]";
JToken filteredData = data.SelectToken($"{filter}");

//We will get
{
  "id": 101,
  "field1": "f1",
  "field2": "f2",
  "InnerArray": [
    {
      "id": 201,
      "innerField1": "f1",
      "innerField2": "f2"
    },
    {
      "id": 202,
      "innerField1": "f1",
      "innerField2": "f2"
    }
  ]
}

但是如果我想通过内部数组元素过滤JSOn,那么它将不起作用

string filter = "$.[?(@.InnerArray[?(@.id==301)])]";
JToken filteredData = data.SelectToken($"{filter}");

//Result is 
{
  "id": 102,
  "field1": "ff1",
  "field2": "ff2",
  "InnerArray": [
    {
      "id": 301,
      "innerField1": "f1",
      "innerField2": "f2"
    },
    {
      "id": 302,
      "innerField1": "f1",
      "innerField2": "f2"
    }
  ]
}

我的期望是

{
  "id": 102,
  "field1": "ff1",
  "field2": "ff2",
  "InnerArray": [
    {
      "id": 301,
      "innerField1": "f1",
      "innerField2": "f2"
    }
  ]
}

InnerArray筛选器不返回所有元素,并且内部JSON PATH不采用,是否有任何其他方法来定义JSON路径?或有任何替代方法可以动态过滤JSON,因为这里JSON将是动态的,过滤器将是动态的

c# json json.net jsonpath
1个回答
0
投票

有可能,我已经构建了以下可执行代码:

我确实不得不将您的示例Json包裹在包装纸中

{ "Array": [...] }

为了使其可分析,否则JObject.Parse表示json无法以数组开头。

string sourceFile = File.ReadAllText("./source.json");
JToken source = JObject.Parse(sourceFile);

List<JToken> tokensToRemove = source.SelectTokens("$..*[?(@.id == 101 || @.id == 301)]").ToList();

tokensToRemove.ForEach(t => t.Remove());

string result = source.ToString();

FYI,$ ..从父级中选择所有元素,而不管其深度如何。

© www.soinside.com 2019 - 2024. All rights reserved.