这是有效的json吗?
{
"a" : "x",
"a" : "y"
}
http://jsonlint.com/的答案是肯定的。
http://www.json.org/没有说任何关于它是禁止的。
但显然这没什么意义,不是吗? 大多数实现可能使用哈希表,所以无论如何它都会被覆盖。
这是有效的json吗?
{
"a" : "x",
"a" : "y"
}
http://jsonlint.com/的答案是肯定的。
http://www.json.org/没有说任何关于它是禁止的。
但显然这没什么意义,不是吗? 大多数实现可能使用哈希表,所以无论如何它都会被覆盖。
当前回答
在c#中,如果你反序列化为Dictionary<string, string>,它接受最后一个键值对:
string json = @"{""a"": ""x"", ""a"": ""y""}";
var d = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
// { "a" : "y" }
如果你试图反序列化到
class Foo
{
[JsonProperty("a")]
public string Bar { get; set; }
[JsonProperty("a")]
public string Baz { get; set; }
}
var f = JsonConvert.DeserializeObject<Foo>(json);
你会得到一个Newtonsoft.Json.JsonSerializationException异常。
其他回答
ECMA JSON标准中没有定义。一般来说,缺乏标准的定义意味着,“不要指望它在任何地方都能以同样的方式工作。”
如果你是一个赌徒,“许多”JSON引擎将允许复制并简单地使用最后指定的值。这样的:
var o = {"a": 1, "b": 2, "a": 3}
变成这样:
Object {a: 3, b: 2}
但如果你不是赌徒,那就别指望了!
在c#中,如果你反序列化为Dictionary<string, string>,它接受最后一个键值对:
string json = @"{""a"": ""x"", ""a"": ""y""}";
var d = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
// { "a" : "y" }
如果你试图反序列化到
class Foo
{
[JsonProperty("a")]
public string Bar { get; set; }
[JsonProperty("a")]
public string Baz { get; set; }
}
var f = JsonConvert.DeserializeObject<Foo>(json);
你会得到一个Newtonsoft.Json.JsonSerializationException异常。
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中发现重复的键时,会考虑来自最后一个键的值。
从标准(p. ii):
预计其他标准将引用此标准,严格遵循JSON文本格式,而 对各种编码细节施加限制。这种标准可能需要具体的行为。JSON 本身不指定任何行为。
在标准(第2页)中,JSON对象的规范如下:
对象结构表示为围绕零个或多个名称/值对的一对花括号标记。 名称是字符串。每个名称后面都有一个冒号标记,将名称与值分开。一个单一的 逗号标记将值与后面的名称分隔开。
它没有提到重复的键是无效的还是有效的,因此根据规范,我可以安全地假设这意味着它们是允许的。
大多数JSON库的实现不接受重复的键,这与标准并不冲突,因为第一个引用。
下面是两个与c++标准库相关的示例。当将一些JSON对象反序列化为std::map时,拒绝重复键是有意义的。但是当将一些JSON对象反序列化为std::multimap时,正常地接受重复键是有意义的。
在处理一个同时接受XML和JSON的API时,我遇到了一个类似的问题,但没有记录它将如何处理您期望在接受的JSON中出现的重复键。
以下是示例JSON的有效XML表示:
<object>
<a>x</a>
<a>y</a>
</object>
当它被转换成JSON时,你会得到以下内容:
{
"object": {
"a": [
"x",
"y"
]
}
}
从一种处理重复键的语言到另一种语言的自然映射,可以作为这里潜在的最佳实践参考。
希望这能帮助到别人!