Does JSON syntax allow duplicate keys in an object?

后端 未结 12 1899
青春惊慌失措
青春惊慌失措 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:15

    From the standard (p. ii):

    It is expected that other standards will refer to this one, strictly adhering to the JSON text format, while imposing restrictions on various encoding details. Such standards may require specific behaviours. JSON itself specifies no behaviour.

    Further down in the standard (p. 2), the specification for a JSON object:

    An object structure is represented as a pair of curly bracket tokens surrounding zero or more name/value pairs. A name is a string. A single colon token follows each name, separating the name from the value. A single comma token separates a value from a following name.

    Diagram for JSON Object

    It does not make any mention of duplicate keys being invalid or valid, so according to the specification I would safely assume that means they are allowed.

    That most implementations of JSON libraries do not accept duplicate keys does not conflict with the standard, because of the first quote.

    Here are two examples related to the C++ standard library. When deserializing some JSON object into a std::map it would make sense to refuse duplicate keys. But when deserializing some JSON object into a std::multimap it would make sense to accept duplicate keys as normal.

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

    The short answer: Yes but is not recommended.
    The long answer: It depends on what you call valid...


    ECMA-404 "The JSON Data Interchange Syntax" doesn't say anything about duplicated names (keys).


    However, RFC 8259 "The JavaScript Object Notation (JSON) Data Interchange Format" says:

    The names within an object SHOULD be unique.

    In this context SHOULD must be understood as specified in BCP 14:

    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.


    RFC 8259 explains why unique names (keys) are good:

    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.



    Also, as Serguei pointed out in the comments: ECMA-262 "ECMAScript® Language Specification", reads:

    In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.

    In other words, last-value-wins.


    Trying to parse a string with duplicated names with the Java implementation by Douglas Crockford (the creator of JSON) results in an exception:

    org.json.JSONException: Duplicate key "status"  at
    org.json.JSONObject.putOnce(JSONObject.java:1076)
    
    0 讨论(0)
  • 2020-11-22 00:21

    There are 2 documents specifying the JSON format:

    1. http://json.org/
    2. https://tools.ietf.org/html/rfc7159

    The accepted answer quotes from the 1st document. I think the 1st document is more clear, but the 2nd contains more detail.

    The 2nd document says:

    1. Objects

      An object structure is represented as a pair of curly brackets surrounding zero or more name/value pairs (or members). A name is a string. A single colon comes after each name, separating the name from the value. A single comma separates a value from a following name. The names within an object SHOULD be unique.

    So it is not forbidden to have a duplicate name, but it is discouraged.

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

    It's not defined in the ECMA JSON standard. And generally speaking, a lack of definition in a standard means, "Don't count on this working the same way everywhere."

    If you're a gambler, "many" JSON engines will allow duplication and simply use the last-specified value. This:

    var o = {"a": 1, "b": 2, "a": 3}
    

    Becomes this:

    Object {a: 3, b: 2}
    

    But if you're not a gambler, don't count on it!

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

    The standard does say this:

    Programming languages vary widely on whether they support objects, and if so, what characteristics and constraints the objects offer. The models of object systems can be wildly divergent and are continuing to evolve. JSON instead provides a simple notation for expressing collections of name/value pairs. Most programming languages will have some feature for representing such collections, which can go by names like record, struct, dict, map, hash, or object.

    The bug is in node.js at least. This code succeeds in node.js.

    try {
         var json = {"name":"n","name":"v"};
         console.log(json); // outputs { name: 'v' }
    } catch (e) {
         console.log(e);
    }
    
    0 讨论(0)
  • 2020-11-22 00:30

    I came across a similar question when dealing with an API that accepts both XML and JSON, but doesn't document how it would handle what you'd expect to be duplicate keys in the JSON accepted.

    The following is a valid XML representation of your sample JSON:

    <object>
      <a>x</a>
      <a>y</a>
    </object>
    

    When this is converted into JSON, you get the following:

    {
      "object": {
        "a": [
          "x",
          "y"
        ]
      }
    }
    

    A natural mapping from a language that handles what you might call duplicate keys to another, can serve as a potential best practice reference here.

    Hope that helps someone!

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