动态解析JSON后如何确定节点是否存在

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态解析JSON后如何确定节点是否存在相关的知识,希望对你有一定的参考价值。

我有以下代码从事件中心读取传入消息并将其存储在Blob存储中。

dynamic msg = JObject.Parse(myEventHubMessage);
WriteToBlob(msg, enqueuedTimeUtc, myEventHubMessage, binder, log);

以下是我收到的JSON的一些示例:


  "deviceId": "ATT",
  "product": "testprod",
  "data": 
    "001": 1,
    "002": 3.1,
    "003": 
      "lat": 0,
      "lng": 0
    ,
    "000": -80
  ,
  "ts": "2020-01-27T19:29:34Z"


      "deviceId": "ATT",
      "product": "testprod",
      "data_in": 
        "ts": "2020-01-27T19:29:34Z",
        "001": 1,
        "002": 3.1,
        "003": 
          "lat": 0,
          "lng": 0
        ,
        "000": -80
      
    

现在,有时设备会发送名称为“ data_in”的节点,而不是JSON中的“数据”节点。 ts字段有时可以在data或data_in节点的内部或外部,并且可能名为timestamp。如何有效确定节点是否存在?

我正在考虑做这样的事情:

if (msg.data_in.ts != null)


而且我会在所有情况下都这样做。有没有办法更好地实现这一目标?同样,如果我检查msg.data_in.ts是否存在data_in节点,则if条件失败。

答案

您的问题是您已将JObject转换为dynamic。由于以下原因,这使事情变得困难:

  • 您松开了所有编译时检查的代码正确性。

  • 您可以轻松方便地访问JObject本身的方法和属性(与动态提供的JSON属性相反)。

    由于JObject实现了诸如JObject之类的接口,将其保留为类型对象将使检查,添加和删除选定JSON属性的工作更加容易。

[要了解为什么使用键入的IDictionary<string, JToken>会更容易,为方便起见,首先介绍以下扩展方法:

JObject

现在您可以按以下方式规范化消息:

public static class JsonExtensions

    public static JProperty Rename(this JProperty old, string newName)
    
        if (old == null)
            throw new ArgumentNullException();
        var value = old.Value;
        old.Value = null;   // Prevent cloning of the value by nulling out the old property's value.
        var @new = new JProperty(newName, value);
        old.Replace(@new);  // By using Replace we preserve the order of properties in the JObject.
        return @new;
    

    public static JProperty MoveTo(this JToken token, JObject newParent)
    
        if (newParent == null || token == null)
            throw new ArgumentNullException();
        var toMove = (token as JProperty ?? token.Parent as JProperty);
        if (toMove == null)
            throw new ArgumentException("Incoming token does not belong to an object.");
        if (toMove.Parent == newParent)
            return toMove;
        toMove.Remove();
        newParent.Add(toMove);
        return toMove;
    

演示小提琴var msg = JObject.Parse(myEventHubMessage); msg.Property("data_in")?.Rename("data"); // Normalize the name "data_in" to be "data". msg["data"]?["ts"]?.MoveTo(msg); // Normalize the position of the "ts" property, it should belong to the root object msg["data"]?["timestamp"]?.MoveTo(msg); // Normalize the position of the "timestamp" property, it should belong to the root object msg.Property("timestamp")?.Rename("ts"); // And normalize the name of the "timestamp" property, it should be "ts".

以上是关于动态解析JSON后如何确定节点是否存在的主要内容,如果未能解决你的问题,请参考以下文章

NodeJs GraphQL 片段解析器

Python3 解析 XML

如何解析包含多个标签的html节点?

如何解析嵌套 JSON 结果中的动态 JSON 键?

使用 SAX 解析器确定是不是在叶节点

是否可以动态编译和执行 C# 代码片段?