这是有效的json吗?

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

http://jsonlint.com/的答案是肯定的。

http://www.json.org/没有说任何关于它是禁止的。

但显然这没什么意义,不是吗? 大多数实现可能使用哈希表,所以无论如何它都会被覆盖。


当前回答

简短的回答是:可以,但不建议使用。 长话短说:这取决于你如何定义有效……

ECMA-404“JSON数据交换语法”没有提到重复的名称(键)。

然而,RFC 8259“JavaScript对象符号(JSON)数据交换格式”规定:

对象中的名称应该是唯一的。

在这种情况下,必须按照BCP 14的规定理解SHOULD:

这个词,或者形容词“RECOMMENDED”,是指那里吗 在特定情况下可能存在有效的理由忽略 特定的项目,但必须充分理解的含义和 在选择不同的路线之前仔细权衡。

RFC 8259解释了为什么唯一的名称(键)是好的:

在某种意义上,名称都是唯一的对象是可互操作的 所有接收该对象的软件实现都会同意 名称-值映射。当对象中的名称不是时 唯一的,软件接收这样一个对象的行为是 不可预测的。许多实现报告姓氏/值对 只有。属性的其他实现报告错误或未能解析 对象,一些实现报告所有的名称/值对, 包括重复。


此外,正如Serguei在评论中指出的那样:ECMA-262“ECMAScript®语言规范”如下:

如果一个对象中有重复的name string,则应覆盖相同键的词法前面的值。

换句话说,最后的价值才是赢家。


试图用Douglas Crockford (JSON的创造者)的Java实现解析具有重复名称的字符串会导致一个异常:

org.json.JSONException: Duplicate key "status"  at
org.json.JSONObject.putOnce(JSONObject.java:1076)

其他回答

ECMA JSON标准中没有定义。一般来说,缺乏标准的定义意味着,“不要指望它在任何地方都能以同样的方式工作。”

如果你是一个赌徒,“许多”JSON引擎将允许复制并简单地使用最后指定的值。这样的:

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

变成这样:

Object {a: 3, b: 2}

但如果你不是赌徒,那就别指望了!

标准是这么说的:

编程语言在是否支持对象和 如果是,对象提供了什么特征和约束。的 对象系统的模型可以有很大的分歧,而且还在继续如此 进化。JSON提供了一个简单的表示符号 名称/值对的集合。大多数编程语言都有 一些用于表示此类集合的特性,这些集合可以按名称命名 比如record, struct, dict, map, hash或object。

这个错误至少在node.js中。这段代码在node.js中成功了。

try {
     var json = {"name":"n","name":"v"};
     console.log(json); // outputs { name: 'v' }
} catch (e) {
     console.log(e);
}

JSON规范是这样说的:

对象是名称/值对的无序集合。

这里重要的部分是“无序的”:它意味着键的唯一性,因为您唯一可以用来引用特定对的是它的键。

此外,大多数JSON库会将JSON对象反序列化为散列映射/字典,其中键是唯一的。反序列化具有重复键的JSON对象时会发生什么情况取决于库:在大多数情况下,您要么会得到一个错误,要么只考虑每个重复键的最后一个值。

例如,在Python中,json。Loads ('{"a": 1, "a": 2}')返回{"a": 2}。

在处理一个同时接受XML和JSON的API时,我遇到了一个类似的问题,但没有记录它将如何处理您期望在接受的JSON中出现的重复键。

以下是示例JSON的有效XML表示:

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

当它被转换成JSON时,你会得到以下内容:

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

从一种处理重复键的语言到另一种语言的自然映射,可以作为这里潜在的最佳实践参考。

希望这能帮助到别人!

因为有很多过时的想法和对标准的困惑。截至2017年12月,有两个相互竞争的标准:

RFC 8259 - https://www.rfc-editor.org/rfc/rfc8259

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

json.org建议ECMA-404是标准,但本网站似乎不是权威。虽然我认为将ECMA视为权威是公平的,但这里重要的是,标准之间的唯一区别(关于唯一密钥)是RFC 8259说密钥应该是唯一的,而ECMA-404说它们不需要是唯一的。

rfc - 8259:

对象中的名称必须是唯一的。

像这样大写的单词“should”在RFC世界中有一个特殊的含义,在另一个标准(BCP 14, RFC 2119 - https://www.rfc-editor.org/rfc/rfc2119)中被明确定义为:

这个词或者形容词“RECOMMENDED”是这个意思吗 在特定情况下,可能存在忽视的正当理由 一个特定的项目,但必须理解全部的含义和 在选择不同的路线之前仔细权衡。

ecma - 404:

JSON语法对所使用的字符串没有任何限制 作为名称,不要求名称字符串是唯一的,也不要求 赋予名称/值对的顺序任何意义。”

无论如何分割,它都是语法上有效的JSON。

RFC 8259中给出的唯一密钥建议的原因是,

在某种意义上,名称都是唯一的对象是可互操作的 所有接收该对象的软件实现都会同意 名称-值映射。当对象中的名称不是时 唯一的,软件接收这样一个对象的行为是 不可预测的。许多实现报告姓氏/值对 只有。属性的其他实现报告错误或未能解析 对象,一些实现报告所有的名称/值对, 包括重复。

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.