0

I have a JSON file that, for now, is validated by hand prior to being placed into production. Ideally, this is an automated process, but for now this is the constraint.

One thing I found helpful in Eclipse were the JSON tools that would highlight duplicate keys in JSON files. Is there similar functionality in Sublime Text or through a plugin?

The following JSON, for example, could produce a warning about duplicate keys.

{
    "a": 1,
    "b": 2,
    "c": 3,
    "a": 4,
    "d": 5
}

Thanks!

Sgt B
  • 1,211
  • 2
  • 11
  • 21

2 Answers2

2

There are plenty of JSON validators available online. I just tried this one and it picked out the duplicate key right away. The problem with using Sublime-based JSON linters like JSONLint is that they use Python's json module, which does not error on extra keys:

import json
json_str = """
{
    "a": 1,
    "b": 2,
    "c": 3,
    "a": 4,
    "d": 5
}"""
py_data = json.loads(json_str) # changes JSON into a Python dict
                               # which is unordered
print(py_data)

yields

{'c': 3, 'b': 2, 'a': 4, 'd': 5}

showing that the first a key is overwritten by the second. So, you'll need another, non-Python-based, tool.

MattDMo
  • 100,794
  • 21
  • 241
  • 231
  • 1
    [using Python's json module doesn't prevent checking for duplicate keys](http://stackoverflow.com/a/14902564/4473405) so the Sublime plugins could be updated to highlight them without much effort. – Keith Hall Dec 22 '15 at 09:29
  • Thanks for the additional information on this. I'll continue to use external validation for the time being until the process is automated. Thanks for the clarification on how python handles this. Perhaps some kind soul can adjust a plugin based on comment from Keith Hall, but that's not my game. Thanks again! – Sgt B Dec 28 '15 at 15:58
2

Even Python documentation says that:

The RFC specifies that the names within a JSON object should be unique, but does not mandate how repeated names in JSON objects should be handled. By default, this module does not raise an exception; instead, it ignores all but the last name-value pair for a given name:

weird_json = '{"x": 1, "x": 2, "x": 3}' json.loads(weird_json) {'x': 3}

The object_pairs_hook parameter can be used to alter this behavior.

So as pointed from docs:

class JsonUniqueKeysChecker:
    def __init__(self):
        self.keys = []

    def check(self, pairs):
        for key, _value in pairs:
            if key in self.keys:
                raise ValueError("Non unique Json key: '%s'" % key)
            else:
                self.keys.append(key)
        return pairs

And then: c = JsonUniqueKeysChecker() print(json.loads(json_str, object_pairs_hook=c.check)) # raises

JSON is very easy format, not very detailed so things like that can be painful. Detection of doubled keys is easy but I bet it's quite a lot of work to forge plugin from that.

Dawid Gosławski
  • 2,028
  • 1
  • 18
  • 25