使用JSON.Net计算JSON文件中的子记录数

时间:2018-05-29 17:59:47

标签: json vb.net json.net

我有以下JSON文件,其中包含许多子记录。这是文件的一个示例:

[{
    "dc:type": {
        "dc:title": "CR",
        "dc:type": "recordType"
    },
    "dc:title": "CCP56778974",
    "Submitted_on": "2011-08-16T16:30:01Z",
    "Drawing": "N",
    "Project": {
        "rdf:about": "ALCX",
        "dc:type": {
            "dc:title": "CR_Project",
            "dc:type": "recordType",
            "rdf:resource": "https://ananh.net/2383783"
        },
        "dc:title": "EMBTCE",
        "Name": "EMBTCE-SysDes"
    },
    "history": {
        "oslc_cm:results": [{
            "dc:type": {
                "dc:title": "history",
                "dc:type": "recordType"
            },
            "dc:title": "Modify",
            "new_state": "Analyzed",
            "action_name": "Modify",
            "old_state": "Analyzed",
            "action_timestamp": "2012-03-09T21:18:27Z"
        },
        {
            "dc:type": {
                "dc:title": "history",
                "dc:type": "recordType"
            },
            "dc:title": "Modify",
            "new_state": "Assigned",
            "action_name": "Modify",
            "old_state": "Assigned",
            "action_timestamp": "2012-03-08T23:53:55Z"
        },
        {
            "dc:type": {
                "dc:title": "history",
                "dc:type": "recordType"
            },
            "dc:title": "Modify",
            "new_state": "Submitted",
            "action_name": "Modify",
            "old_state": "Submitted",
            "action_timestamp": "2011-08-16T16:54:56Z"
        }],
        "oslc_cm:collref": "http://UYBNYRTCVV.com/47474"
    },
    "Engineer": {
        "dc:type": {
            "dc:title": "users",
            "dc:type": "recordType"
        }
    },
    "rdf:about": "https://GHNMUN.com/7546756"
}]

我需要计算“action_name”的数量。结果必须是3。 到目前为止,我已经做到了这一点:

  Dim jResults As Object = Linq.JObject.Parse(rawdata)
  lRecords = jResults("oslc_cm:results").count

但这不计算[oslc_cm:results]下的子记录。

如何正确计算嵌套的“action_name”属性?

1 个答案:

答案 0 :(得分:0)

您有兴趣计算的属性"action_name"嵌套在路径"[0].history.oslc_cm:results[0,1,2].action_name"的JSON深处。您可以使用JToken.SelectTokens(string path)查找并统计所有此类令牌,​​无论它们位于JSON层次结构中,都可以SelectTokens supports JSONPath - XPath for JSON查询语法。

如果要在JSON层次结构中的任何位置查找并计算所有"action_name"属性,您可以执行以下操作:

Dim path = "..action_name"

Dim jResults = Newtonsoft.Json.Linq.JToken.Parse(rawdata)
Dim query = jResults.SelectTokens(path)
Dim count = query.Count()

另一方面,如果您只想查找某些指定数组中的所有"action_name"属性,请改用以下路径:

Dim path = "[*].history.oslc_cm:results[*].action_name"

注意:

  • 您最外面的JSON容器是一个数组 - 由[]包围的以逗号分隔的值序列。因此,它无法解析为表示JSON 对象的JObject - 由大括号包围的逗号分隔的名称/值对集合。相反,您需要将其解析为可以表示数组的LINQ to JSON类型。

    我选择JToken这是任何JSON令牌的抽象基类型。任何格式良好的JSON都可以解析为JToken

  • 在JSONPath查询中,".."递归下降运算符,因此"..action_name"会在JSON中找到名为action_name的所有属性。

  • 相反,"*"通配符运算符。它在层次结构中的当前位置查找所有对象或元素,而不管它们的名称。 ".""[]"是子操作符。

    因此"[*].history.oslc_cm:results[*].action_name"找到属于属性的所有元素的名为action_name的属性属于属性为根数组的所有元素的对象属性oslc_cm:results

  • history的正确命名空间为Newtonsoft.Json.Linq

示例工作VB.NET小提琴here