这是有效的json吗?
{
"a" : "x",
"a" : "y"
}
Run Code Online (Sandbox Code Playgroud)
http://www.json.org/没有说明被禁止的事情.
但显然它没有多大意义,是吗?大多数实现可能使用哈希表,因此无论如何它都被覆盖.
use*_*322 111
简短回答:是的,但不推荐.
答案很长:这取决于你所谓的有效...
该JSON数据交换格式(ECMA-404)并没有说明重复名称(键)任何东西.
但是,JavaScript Object Notation(JSON)数据交换格式(RFC7159)说:
对象中的名称应该是唯一的.
在这种情况下,必须按照RFC 2119中的规定来理解
应该这个词,或形容词"推荐",意味着在特定情况下可能存在忽略特定项目的正当理由,但在选择不同的课程之前必须理解并仔细权衡全部含义.
RFC 7159解释了为什么唯一名称(键)是好的:
名称都是唯一的对象是可互操作的,因为
接收该对象的所有软件实现都将同意名称 - 值映射.当对象中的名称不
唯一时,接收此类对象的软件的行为是
不可预测的.许多实现仅报告姓氏/值对
.其他实现报告错误或无法解析
对象,并且一些实现报告所有名称/值对,
包括重复.已经观察到JSON解析库的不同之处在于它们是否使对象成员的排序对调用软件可见.其行为不依赖于成员
排序的实现将是可互操作的,因为它们不会
受到这些差异的影响.
此外,正如Serguei在评论中指出的那样:ECMA-262 "ECMAScript®语言规范",内容如下:
如果对象中存在重复的名称字符串,则应覆盖相同键的词法上先前的值.
(换句话说,最后一次胜利).
尝试使用Douglas Crockford(JSON的创建者)的Java实现来解析具有重复名称的字符串会导致异常:
org.json.JSONException: Duplicate key "status" at
org.json.JSONObject.putOnce(JSONObject.java:1076)
Run Code Online (Sandbox Code Playgroud)
Tim*_*lds 107
从标准(第二部分):
预计其他标准将引用此标准,严格遵守JSON文本格式,同时对各种编码细节施加限制.这些标准可能需要特定的行为.JSON本身不指定任何行为.
在标准中进一步向下(第2页),JSON对象的规范:
对象结构表示为围绕零个或多个名称/值对的一对大括号标记.名称是一个字符串.每个名称后面都有一个冒号标记,将名称与值分开.单个逗号标记将值与以下名称分隔开.
它没有提到重复密钥无效或有效,因此根据规范我会安全地假设这意味着它们是允许的.
由于第一个引用,大多数JSON库实现不接受重复键与标准不冲突.
以下是与C++标准库相关的两个示例.将一些JSON对象反序列化为一个std::map时,拒绝重复键是有意义的.但是当将一些JSON对象反序列化为一个std::multimap时,正常接受重复键是有意义的.
too*_*ges 18
有2个文档指定JSON格式:
接受的答案引用了第一份文件.我认为第一个文件更清楚,但第二个文件包含更多细节.
第二份文件说:
对象
对象结构表示为围绕零个或多个名称/值对(或成员)的一对花括号.名称是一个字符串.每个名称后面都有一个冒号,将名称与值分开.单个逗号将值与以下名称分隔开. 对象中的名称应该是唯一的.
所以不禁止有重复的名称,但不鼓励.
在处理接受XML和JSON的API时,我遇到了类似的问题,但没有记录它如何处理您希望接受的JSON中的重复键.
以下是示例JSON的有效XML表示形式:
<object>
<a>x</a>
<a>y</a>
</object>
Run Code Online (Sandbox Code Playgroud)
将其转换为JSON时,您将获得以下内容:
{
"object": {
"a": [
"x",
"y"
]
}
}
Run Code Online (Sandbox Code Playgroud)
从处理可能称为重复键的语言到另一个键的语言的自然映射可以作为潜在的最佳实践参考.
希望有人帮助!
JSON规范说:
对象是一组无序的名称/值对.
这里的重要部分是"无序":它意味着键的唯一性,因为您可以用来引用特定对的唯一因素是它的关键.
此外,大多数JSON库将JSON对象反序列化为哈希映射/字典,其中密钥保证唯一.使用重复键反序列化JSON对象时会发生什么情况取决于库:在大多数情况下,您将获得错误,或者只考虑每个重复键的最后一个值.
例如,在Python中,json.loads('{"a": 1, "a": 2}')返回{"a": 2}.
小智 6
发布和回答,因为有很多关于标准的过时的想法和混乱。截至 2017 年 12 月,有两个相互竞争的标准:
RFC 8259 - https://tools.ietf.org/html/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:
“对象内的名称应该是唯一的。”
像这样的所有大写字母中的“应该”一词在 RFC 世界中具有含义,在另一个标准(BCP 14、RFC 2119 - https://tools.ietf.org/html/rfc2119)中明确定义为,
- 应该这个词,或形容词“推荐”,表示在特定情况下可能存在有效理由忽略特定项目,但在选择不同的课程之前必须理解并仔细权衡全部含义。
ECMA-404:
“JSON 语法不对用作名称的字符串施加任何限制,不要求名称字符串是唯一的,并且不对名称/值对的排序赋予任何意义。”
所以,无论你如何切片,它在语法上都是有效的 JSON。
RFC 8259 中给出的唯一密钥建议的原因是,
名称都是唯一的对象是可互操作的,因为接收该对象的所有软件实现都将同意名称-值映射。当对象内的名称不唯一时,接收此类对象的软件的行为是不可预测的。许多实现仅报告姓氏/值对。其他实现会报告错误或无法解析对象,有些实现会报告所有名称/值对,包括重复项。
换句话说,从 RFC 8259 的角度来看,它是有效的,但您的解析器可能会失败,并且无法保证哪个值(如果有)与该键配对。从 ECMA-404 的观点(我个人认为是权威)来看,它是有效的。对我来说,这意味着任何拒绝解析它的解析器都会被破坏。它至少应该根据这两个标准进行解析。但是它如何变成您选择的本机对象,在任何情况下,是否是唯一键,完全取决于环境和情况,而这些都不是开始时的标准。
小智 5
应该是唯一的并不意味着必须是唯一的。然而,如上所述,一些解析器会失败,而另一些解析器只会使用最后解析的值。但是,如果对规范进行了一些清理以允许重复,那么我可以看到一种用途,您可能有一个事件处理程序,该事件处理程序将 JSON 转换为 HTML 或其他格式...在这种情况下,它完全有效解析 JSON 并创建另一种文档格式...
[
"div":
{
"p": "hello",
"p": "universe"
},
"div":
{
"h1": "Heading 1",
"p": "another paragraph"
}
]
Run Code Online (Sandbox Code Playgroud)
然后可以轻松解析为 html,例如:
<body>
<div>
<p>hello</p>
<p>universe</p>
</div>
<div>
<h1>Heading 1</h1>
<p>another paragraph</p>
</div>
</body>
Run Code Online (Sandbox Code Playgroud)
我可以看到这个问题背后的原因,但就目前情况而言......我不会相信它。