Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JSON语法是否允许对象中存在重复键?_Json_Standards - Fatal编程技术网

JSON语法是否允许对象中存在重复键?

JSON语法是否允许对象中存在重复键?,json,standards,Json,Standards,这是有效的json吗 { "a" : "x", "a" : "y" } 他说是的 没有说这是被禁止的 但很明显这没有多大意义,是吗? 大多数实现可能使用哈希表,因此无论如何都会覆盖它。在C#中,如果反序列化到字典,则会使用最后一个键值对: string json = @"{""a"": ""x"", ""a"": ""y""}"; var d = JsonConvert.DeserializeObject<Dictionary<string, string>&

这是有效的json吗

{
    "a" : "x",
    "a" : "y"
}
他说是的

没有说这是被禁止的

但很明显这没有多大意义,是吗? 大多数实现可能使用哈希表,因此无论如何都会覆盖它。

在C#中,如果反序列化到
字典
,则会使用最后一个键值对:

string json = @"{""a"": ""x"", ""a"": ""y""}";
var d = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
// { "a" : "y" }
stringjson=@“{”a“:”x“,”a“:”y“}”;
var d=JsonConvert.DeserializeObject(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);
class-Foo
{
[JsonProperty(“a”)]
公共字符串条{get;set;}
[JsonProperty(“a”)]
公共字符串Baz{get;set;}
}
var f=JsonConvert.DeserializeObject(json);
您将从以下位置获得一个
Newtonsoft.Json.JsonSerializationException
异常。

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

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

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

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

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


这里有两个与C++标准库相关的例子。当将某个JSON对象反序列化为

std::map
时,拒绝重复的键是有意义的。但是,当将某个JSON对象反序列化为
std::multimap
时,可以正常接受重复键

对象是一组无序的名称/值对

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

此外,大多数JSON库将JSON对象反序列化为哈希映射/字典,其中键保证唯一。使用重复键反序列化JSON对象时会发生什么情况取决于库:在大多数情况下,要么会出现错误,要么只考虑每个重复键的最后一个值

例如,在Python中,
json.loads(“{”a“:1,“a“:2}”)
返回
{”a“:2}

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

如果您是一个赌徒,“许多”JSON引擎将允许复制,并且只使用最后指定的值。这:

var o = {"a": 1, "b": 2, "a": 3}
变成这样:

Object {a: 3, b: 2}

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

简短回答:是,但不推荐。
答案很长:这取决于你所说的有效…


“JSON数据交换语法”没有提到任何关于重复名称(键)的内容


但是,“JavaScript对象表示法(JSON)数据交换格式”表示:

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

在这种情况下,必须理解为:

这个词或形容词“推荐”的意思应该是 在特定情况下,可能存在忽略 特定项目,但必须理解和理解其全部含义 在选择不同的课程之前仔细权衡


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

名称都是唯一的对象在某种意义上是可互操作的 所有接收该对象的软件实现都将同意 名称-值映射。当对象中的名称不是 唯一性,接收此类对象的软件的行为是 不可预知的许多实现报告姓氏/值对 只有其他实现报告错误或无法解析 对象,一些实现报告所有的名称/值对, 包括副本



此外,正如Serguei在评论中指出的:“ECMAScript®语言规范”内容如下:

如果对象中存在重复的名称字符串,则应覆盖同一键的词汇上的前导值

换句话说,最后一个值获胜


尝试使用(JSON的创建者)解析名称重复的字符串:


该标准确实指出:

编程语言在是否支持对象以及 如果是,对象提供了哪些特征和约束。这个 对象系统的模型可能会有很大的差异,并且会继续变化 发展JSON提供了一个简单的符号来表示 名称/值对的集合。大多数编程语言都有 一些用于表示此类集合的功能,这些集合可以按名称排列 例如记录、结构、dict、映射、哈希或对象

错误至少在node.js中。此代码在node.js中成功

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

问目的,有不同的答案:

使用JSON序列化对象(JavaScriptObjectNotation),每个字典元素映射到一个独立的对象属性,因此为同一属性定义值的不同条目没有意义

然而,我在一个非常具体的用例中遇到了同样的问题: 在编写用于API测试的JSON示例时,我想知道如何在不破坏可用性的情况下向JSON文件中添加注释。JSON规范不知道注释,因此我提出了一个非常简单的方法:

使用重复键对JSON示例进行注释
try {
     var json = {"name":"n","name":"v"};
     console.log(json); // outputs { name: 'v' }
} catch (e) {
     console.log(e);
}
<object>
  <a>x</a>
  <a>y</a>
</object>
{
  "object": {
    "a": [
      "x",
      "y"
    ]
  }
}
[
  "div":
  {
    "p": "hello",
    "p": "universe"
  },
  "div":
  {
    "h1": "Heading 1",
    "p": "another paragraph"
  }
]
<body>
 <div>
  <p>hello</p>
  <p>universe</p>
 </div>
 <div>
  <h1>Heading 1</h1>
  <p>another paragraph</p>
 </div>
</body>