Jackson JSON:逐个遍历JSON树节点

4
我有许多包含json数据的文本文件,并且我正在使用Jackson json解析器中的new ObjectMapper().readTree()方法将json数据解析为DOM树。现在假设我有两个DOM树-t1和t2。每个树都将有许多子节点,这些子节点又将有许多子节点。我想做的是逐个遍历树t1的每个节点,并将t1中的每个节点与t2中的每个节点进行比较。我知道Jackson json解析器允许我查询特定节点,但是如何逐个遍历整个树的每个节点呢?
3个回答

4
您可以简单地使用JsonNode.iterator()方法获取节点的所有子节点(到您需要的级别)。 您可以检查节点JsonNode.isArrayJsonNode.isObject或任何其他类型,以停止深度优先搜索。您需要的其他一切都与树遍历相关。

是的,我可以使用JsonNode.iterator()来实现。但是我需要节点下的整个子树(包括任何子节点下的子树),这就是为什么我应该使用gbegley建议的递归函数。谢谢! - athreya86
但是使用 Eugene 建议的方法 (JsonNode.iterator),您可以完全做到这一点。您可以递归进入任何深度的子树 (JsonNode 本身),除非当前节点找到 isArray 或 isObject。您所需要做的就是在方法内部连接递归调用即可。 - daniel.kahlenberg

2
如果你只是想比较t1和t2,可以简单地写成t1.equals(t2)。我假设t1和t2是JsonNode类型,并且已经实现了equals方法。

1
 boolean NodesEqual(JsonNode n1, JsonNode n2) {
  if(n1.size()!=n2.size())return false;
  // ... other equality checks, like name, data type, etc
  for(int i=0;i<n.size();i++){
    JsonNode child1 = n1.get(i);
    JsonNode child2 = n2.get(i);
    if(!NodesEqual(child1,child2)) return false;
  } 
  return true;
 }

这是一个递归函数,因此大型、深度嵌套的文档可能会出现问题,但对于普通情况应该可以正常工作。


我的JSON文档嵌套非常深。但是,我将尝试使用您上面提供的函数,并根据需要进行更改。如果文档嵌套很深,您有任何建议/改进措施吗?谢谢。 - athreya86
除非您的嵌套深度超过数千层,否则您应该没有问题。在这种情况下,您可能会遇到VM堆栈大小的问题,但是我怀疑您首先会遇到TreeMapper相同的问题。如果确实如此,那么您可以使用非递归实现,但这些代码会更冗长。请参见此处以开始。 - gbegley
Staxman可能是对的,查看JSONNode ObjectNode子类源代码(equals实现从第533行开始)以查看是否适用于您。 - gbegley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接