How to find parent Json node while parsing a JSON

2019-06-17 00:38发布

I am parsing a JSON Stream using Jackson.

API that I am using is ObjectMapper.readTree(..)

Consider following stream:

{
  "type": "array",
  "items": {
      "id": "http://example.com/item-schema",
      "type": "object",
      "additionalProperties": {"$ref": "#"}
  }
}

Now when I read additionalProperties, I figure out there is a "$ref" defined here. Now to resolve the reference, I need to go to its parent and figure out the id (to resolve the base schema).

I can't find any API to go to parent of JsonNode holding additionalProperties. Is there a way I can achieve this?

Info:

Why I need this is I need to find the base schema against which $ref has to be resolved. And to figure out base schema, I need to know the id of its parents..

3条回答
干净又极端
2楼-- · 2019-06-17 01:16

Got it!

@Override
public void serialize(ObjectId value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
    JsonStreamContext parent = jgen.getOutputContext().getParent();
    // Win!
}
查看更多
Juvenile、少年°
3楼-- · 2019-06-17 01:27

Jackson JSON Trees are singly-linked, there is no parent linkage. This has the benefit of reduced memory usage (since many leaf-level nodes can be shared) and slightly more efficient building, but downside of not being able to traverse up and down the hierarchy.

So you will need to keep track of that yourself, or use your own tree model.

查看更多
老娘就宠你
4楼-- · 2019-06-17 01:40

I am not able to understand the exact context of your problem. But I was doing some similar thing where I had to find a property value and then change it if the value meets some sort of criteria.

To search the value node I used at function with JsonPointer and to go to Parent I used JsonPointer.head function and used at again on root json node.

example as below

ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(JsonString);
JsonPointer valueNodePointer = JsonPointer.compile("/GrandObj/Obj/field");
JsonPointer containerPointer = valueNodePointer.head();
JsonNode parentJsonNode = rootNode.at(containerPointer);

//above is what you asked for as per my understanding
//following you can use to update the value node just for 
//the sake of completeness why someone really look for parent
//node
if (!parentJsonNode.isMissingNode() && parentJsonNode.isObject()) {
    ObjectNode parentObjectNode = (ObjectNode) parentJsonNode;
    //following will give you just the field name. e.g. if pointer is /grandObject/Object/field
    //JsonPoint.last() will give you /field 
    //remember to take out the / character 
    String fieldName = valueNodePointer.last().toString();
    fieldName = fieldName.replace(Character.toString(JsonPointer.SEPARATOR), StringUtils.EMPTY);
    JsonNode fieldValueNode = parentObjectNode.get(fieldName);
    if(fieldValueNode != null) {
        parentObjectNode.put(fieldName, 'NewValue');
    }
}
查看更多
登录 后发表回答