这是有效的json吗?

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

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

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

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


当前回答

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

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

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

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

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

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

希望这能帮助到别人!

其他回答

标准是这么说的:

编程语言在是否支持对象和 如果是,对象提供了什么特征和约束。的 对象系统的模型可以有很大的分歧,而且还在继续如此 进化。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);
}

从标准(p. ii):

预计其他标准将引用此标准,严格遵循JSON文本格式,而 对各种编码细节施加限制。这种标准可能需要具体的行为。JSON 本身不指定任何行为。

在标准(第2页)中,JSON对象的规范如下:

对象结构表示为围绕零个或多个名称/值对的一对花括号标记。 名称是字符串。每个名称后面都有一个冒号标记,将名称与值分开。一个单一的 逗号标记将值与后面的名称分隔开。

它没有提到重复的键是无效的还是有效的,因此根据规范,我可以安全地假设这意味着它们是允许的。

大多数JSON库的实现不接受重复的键,这与标准并不冲突,因为第一个引用。

下面是两个与c++标准库相关的示例。当将一些JSON对象反序列化为std::map时,拒绝重复键是有意义的。但是当将一些JSON对象反序列化为std::multimap时,正常地接受重复键是有意义的。

因为有很多过时的想法和对标准的困惑。截至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.

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.

从实际应用中,我已经看到,当在JSON中发现重复的键时,会考虑来自最后一个键的值。

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

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

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

变成这样:

Object {a: 3, b: 2}

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