Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove properties from JSON object not present in schema?

I am using Python's jsonschema to validate JSON files against a schema. It works great. But now I need to remove any properties from my JSON that are not present in the schema.

I know that according to the JSON Schema docs, I can set the property:

additionalProperties = false

to reject any files with additional properties. But this will just reject the properties, not actually remove them.

What is the best way to remove them?

I guess I can write my own script that:

  • walks every leaf node of the JSON file
  • checks whether the leaf node exists in the schema
  • if it does not, walks up the tree until it finds the highest node that does exist, then prunes the branch at that point.

My question is: is there an existing Python library to do this, or do I need to write one? I have Googled, but without any success.

like image 286
Richard Avatar asked Jun 22 '17 09:06

Richard


People also ask

How do I remove an object from a JSON file?

To delete a JSON object from a list: Parse the JSON object into a Python list of dictionaries. Use the enumerate() function to iterate over the iterate over the list. Check if each dictionary is the one you want to remove and use the pop() method to remove the matching dict.

What does $Ref mean in JSON Schema?

In a JSON schema, a $ref keyword is a JSON Pointer to a schema, or a type or property in a schema. A JSON pointer takes the form of A # B in which: A is the relative path from the current schema to a target schema. If A is empty, the reference is to a type or property in the same schema, an in-schema reference.

How do I delete a variable in JSON?

delete operator is used to remove an object property . delete operator does not returns the new object, only returns a boolean : true or false. In the other hand, after interpreter executes var updatedjsonobj = delete myjsonobj['otherIndustry']; , updatedjsonobj variable will store a boolean value.


1 Answers

You could extend the validator. A similar implementation is used for default values.

A little bit late, but here is a solution.

I extend the validator to override validation of properties keyword. If one of properties exists in instance but not in the schema, I remove it from the instance.

from jsonschema import Draft7Validator, validators

def extend_validator(validator_class):
    validate_properties = validator_class.VALIDATORS["properties"]

    def remove_additional_properties(validator, properties, instance, schema):
        for prop in list(instance.keys()):
            if prop not in properties:
                del instance[prop]

        for error in validate_properties(
            validator, properties, instance, schema,
        ):
            yield error

    return validators.extend(
        validator_class, {"properties" : remove_additional_properties},
    )

DefaultValidatingDraft7Validator = extend_validator(Draft7Validator)

# Example usage:
obj = {
    'foo': 'bar',
    'not_in_schema': 'no no no'
}
schema = {
    'properties': {
        'foo': {
            'type': 'string'
        }
    }
}

DefaultValidatingDraft7Validator(schema).validate(obj)
assert obj == {'foo': 'bar'}
like image 174
Raphael Medaer Avatar answered Oct 22 '22 18:10

Raphael Medaer