Does JSON syntax allow duplicate keys in an object?

后端 未结 12 1913
青春惊慌失措
青春惊慌失措 2020-11-22 00:05

Is this valid json?

{
    \"a\" : \"x\",
    \"a\" : \"y\"
}

http://jsonlint.com/ says yes.

http://www.json.org/ doesn\'t say anyth

相关标签:
12条回答
  • 2020-11-22 00:05

    Posting and answer because there is a lot of outdated ideas and confusion about the standards. As of December 2017, there are two competing standards:

    RFC 8259 - https://tools.ietf.org/html/rfc8259

    ECMA-404 - http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf

    json.org suggests ECMA-404 is the standard, but this site does not appear to be an authority. While I think it's fair to consider ECMA the authority, what's important here is, the only difference between the standards (regarding unique keys) is that RFC 8259 says the keys should be unique, and the ECMA-404 says they are not required to be unique.

    RFC-8259:

    "The names within an object SHOULD be unique."

    The word "should" in all caps like that, has a meaning within the RFC world, that is specifically defined in another standard (BCP 14, RFC 2119 - https://tools.ietf.org/html/rfc2119) as,

    1. SHOULD This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

    ECMA-404:

    "The JSON syntax does not impose any restrictions on the strings used as names, does not require that name strings be unique, and does not assign any significance to the ordering of name/value pairs."

    So, no matter how you slice it, it's syntactically valid JSON.

    The reason given for the unique key recommendation in RFC 8259 is,

    An object whose names are all unique is interoperable in the sense that all software implementations receiving that object will agree on the name-value mappings. When the names within an object are not unique, the behavior of software that receives such an object is unpredictable. Many implementations report the last name/value pair only. Other implementations report an error or fail to parse the object, and some implementations report all of the name/value pairs, including duplicates.

    In other words, from the RFC 8259 viewpoint, it's valid but your parser may barf and there's no promise as to which, if any, value will be paired with that key. From the ECMA-404 viewpoint (which I'd personally take as the authority), it's valid, period. To me this means that any parser that refuses to parse it is broken. It should at least parse according to both of these standards. But how it gets turned into your native object of choice is, in any case, unique keys or not, completely dependent on the environment and the situation, and none of that is in the standard to begin with.

    0 讨论(0)
  • 2020-11-22 00:06

    SHOULD be unique does not mean MUST be unique. However, as stated, some parsers would fail and others would just use the last value parsed. However, if the spec was cleaned up a little to allow for duplicates then I could see a use where you may have an event handler which is transforming the JSON to HTML or some other format... In such cases it would be perfectly valid to parse the JSON and create another document format...

    [
      "div":
      {
        "p": "hello",
        "p": "universe"
      },
      "div":
      {
        "h1": "Heading 1",
        "p": "another paragraph"
      }
    ]
    

    could then easily parse to html for example:

    <body>
     <div>
      <p>hello</p>
      <p>universe</p>
     </div>
     <div>
      <h1>Heading 1</h1>
      <p>another paragraph</p>
     </div>
    </body>
    

    I can see the reasoning behind the question but as it stands... I wouldn't trust it.

    0 讨论(0)
  • 2020-11-22 00:06

    Asking for purpose, there are different answers:

    Using JSON to serialize objects (JavaScriptObjectNotation), each dictionary element maps to an indivual object property, so different entries defining a value for the same property has no meaning.

    However, I came over the same question from a very specific use case: Writing JSON samples for API testing, I was wondering how to add comments into our JSON file without breaking the usability. The JSON spec does not know comments, so I came up with a very simple approach:

    To use duplicate keys to comment our JSON samples. Example:

    { "property1" : "value1", "REMARK" : "... prop1 controls ...", "property2" : "value2", "REMARK" : "... value2 raises an exception ...", }

    The JSON serializers which we are using have no problems with these "REMARK" duplicates and our application code simply ignores this little overhead.

    So, even though there is no meaning on the application layer, these duplicates for us provide a valuable workaround to add comments to our testing samples without breaking the usability of the JSON.

    0 讨论(0)
  • 2020-11-22 00:09

    According to RFC-7159, the current standard for JSON published by the Internet Engineering Task Force (IETF), states "The names within an object SHOULD be unique". However, according to RFC-2119 which defines the terminology used in IETF documents, the word "should" in fact means "... there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course." What this essentially means is that while having unique keys is recommended, it is not a must. We can have duplicate keys in a JSON object, and it would still be valid.

    From practical application, I have seen the value from the last key is considered when duplicate keys are found in a JSON.

    0 讨论(0)
  • 2020-11-22 00:10

    In C# if you deserialise to a Dictionary<string, string> it takes the last key value pair:

    string json = @"{""a"": ""x"", ""a"": ""y""}";
    var d = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
    // { "a" : "y" }
    

    if you try to deserialise to

    class Foo
    {
        [JsonProperty("a")]
        public string Bar { get; set; }
    
        [JsonProperty("a")]
        public string Baz { get; set; }
    }
    
    var f = JsonConvert.DeserializeObject<Foo>(json);
    

    you get a Newtonsoft.Json.JsonSerializationException exception.

    0 讨论(0)
  • 2020-11-22 00:12

    The JSON spec says this:

    An object is an unordered set of name/value pairs.

    The important part here is "unordered": it implies uniqueness of keys, because the only thing you can use to refer to a specific pair is its key.

    In addition, most JSON libs will deserialize JSON objects to hash maps/dictionaries, where keys are guaranteed unique. What happens when you deserialize a JSON object with duplicate keys depends on the library: in most cases, you'll either get an error, or only the last value for each duplicate key will be taken into account.

    For example, in Python, json.loads('{"a": 1, "a": 2}') returns {"a": 2}.

    0 讨论(0)
提交回复
热议问题