Позволяет ли синтаксис JSON дублировать ключи в объекте?



это допустимый json?



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


http://jsonlint.com/ говорит "Да".



http://www.json.org/ ничего не говорит о том, что это запрещено.



но очевидно, что это не имеет большого смысла, не так ли?
Большинство реализаций, вероятно, используют хэш-таблицу, поэтому она переопределяется в любом случае.

1796   11  

11 ответов:

С стандарт (стр. ii):

ожидается, что другие стандарты будут ссылаться на этот, строго придерживаясь текстового формата JSON, в то время как наложение ограничений на различные детали кодирования. Такие стандарты могут требовать определенного поведения. формат JSON сама по себе не определяет поведения.

далее в стандарте (стр. 2), спецификация для объекта JSON:

структура объекта представляется в виде фигурные скобки маркеры окружающих ноль или более пар имя/значение. Имя-это строка. За каждым именем следует один маркер двоеточия, отделяющий имя от значения. Сингл запятая маркер отделяет значение от следующего имени.

Diagram for JSON Object

Он не упоминает о том, что дубликаты ключей недействительны или действительны, поэтому в соответствии со спецификацией я бы с уверенностью предположил, что это означает, что они разрешены.

что большинство реализаций Библиотеки JSON делают не принять дубликаты ключей не конфликтует со стандартом, из-за первой цитаты.

вот два примера, связанные со стандартной библиотекой C++. При десериализации некоторого объекта JSON в std::map было бы разумно отказаться от дубликатов ключей. Но при десериализации некоторого объекта JSON в std::multimap было бы разумно принять дубликаты ключей как обычно.

короткий ответ: Да, но не рекомендуется.
Длинный ответ: Это зависит от того, что вы называете действительным...


Элемент формат обмена данными JSON (ECMA-404) ничего не говорит о дублированных именах (ключах).

однако, формат обмена данными JavaScript Object Notation (JSON) (RFC7159) говорит:

имена внутри объекта должны быть уникальный.

в этой связи должны следует понимать как указано в RFC 2119

должно ли это слово или прилагательное "рекомендуется" означать, что может быть существуют веские причины в конкретных обстоятельствах игнорировать конкретный пункт, но все последствия должны быть поняты и тщательно взвешивают, прежде чем выбрать другой курс.



RFC 7159 объясняет, почему уникальный имена (ключи) хороши:

объект, имена которого все уникальны, является совместимым в смысле
что все программные реализации, получающие этот объект, согласятся имя-значение сопоставления. Когда имена внутри объекта не
уникальный, поведение программного обеспечения, которое получает такой объект
непредсказуемый. Многие реализации сообщают о паре фамилия / значение
только. Другие реализации сообщают об ошибке или не удается проанализировать элемент
объект и некоторые реализации сообщают обо всех парах имя / значение,
в том числе и дубликаты.

библиотеки синтаксического анализа JSON, как было замечено, отличаются друг от друга или нет, они делают порядок элементов объекта видимым для вызова программное обеспечение. Реализации, поведение которых не зависит от member
заказ полностью совместимых в том смысле, что они не будут
пострадавшие от них различия.




Также, Как отметил Сергей в комментариях:ECMA-262 " спецификация языка ECMAScript®", читает:

в случае, когда в объекте имеются повторяющиеся строки имен, лексически предшествующие значения для одного и того же ключа должны быть перезаписаны.

(другими словами last-value-wins).




пытаюсь разобрать строка с дублированными именами с реализация Java Дугласом Крокфордом (создатель JSON) приводит к исключению:

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

есть 2 документа, определяющих формат JSON:

  1. http://json.org/
  2. https://tools.ietf.org/html/rfc7159

принятый ответ цитирует из 1-го документа. Я думаю, что 1-й документ более ясен, но 2-й содержит больше деталей.

второй документ гласит:

  1. объекты

    структура объекта представлена в виде пары фигурных скобок окружение нуля или более пар имя/значение (или членов). Имя это строка. Один двоеточие приходит после каждого имени, разделяя имя от значения. Одна запятая отделяет значение от следующего имя. имена внутри объекта должны быть уникальными.

Так что это не запрещено иметь дубликат имени, но это не рекомендуется.

я столкнулся с аналогичным вопросом при работе с API, который принимает как XML, так и JSON, но не документирует, как он будет обрабатывать то, что вы ожидаете, чтобы быть дубликатами ключей в принятом JSON.

ниже приведено допустимое XML-представление вашего образца JSON:

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

когда это преобразуется в JSON, вы получаете следующее:

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

естественное отображение из языка, который обрабатывает то, что вы могли бы назвать дубликатами ключей к другому, может служить в качестве потенциальной ссылки на передовую практику здесь.

надеюсь, что это поможет кому-то!

спецификация JSON говорит следующее:

объект-неупорядоченный набор пар имя/значение.

важная часть здесь "неупорядоченная": она подразумевает уникальность ключей, потому что единственное, что вы можете использовать для ссылки на конкретную пару, - это ее ключ.

кроме того, большинство библиотек JSON десериализуют объекты JSON в хэш-карты/словари, где ключи гарантированно уникальны. Что происходит при десериализации объекта JSON с повторяющимися ключами зависит в библиотеке: в большинстве случаев вы либо получите ошибку, либо будет учтено только последнее значение для каждого дубликата ключа.

например, в Python, json.loads('{"a": 1, "a": 2}') возвращает {"a": 2}.

спрашивая о цели, есть разные ответы:

используя JSON для сериализации объектов (JavaScriptObjectNotation), каждый элемент словаря сопоставляется с индивидуальным свойством объекта, поэтому разные записи, определяющие значение для одного и того же свойства, не имеют смысла.

тем не менее, я пришел к тому же вопросу из очень конкретного случая использования: Написание образцов JSON для тестирования API, мне было интересно, как добавить комментарии в наш файл JSON, не нарушая удобство использования. Спецификация JSON не знаю комментариев, поэтому я придумал очень простой подход:

чтобы использовать дубликаты ключей, чтобы прокомментировать наши образцы JSON. Пример:

{ "property1" : "value1", "REMARK" : "... prop1 controls ...", "property2" : "value2", "REMARK" : "... value2 raises an exception ...", }

сериализаторы JSON, которые мы используем, не имеют проблем с этими дубликатами" примечаний", и наш код приложения просто игнорирует эти небольшие накладные расходы.

Итак, хотя на прикладном уровне нет смысла, эти дубликаты для нас предоставляют ценный обходной путь для добавления комментарии к нашим тестовым образцам без нарушения удобства использования JSON.

должен быть уникальным не означает должен быть уникальным. Однако, как указано, некоторые Парсеры потерпят неудачу,а другие будут просто использовать последнее значение, проанализированное. Однако, если спецификация была немного очищена, чтобы разрешить дубликаты, я мог бы увидеть использование, где у вас может быть обработчик событий, который преобразует JSON в HTML или какой-либо другой format...in в таких случаях было бы совершенно правильно проанализировать JSON и создать другой формат документа...

[
  "div":
  {
    "p":"hello",
    "p":"universe"
  }
  "div":
  {
    "h1":"Heading 1",
    "p":"another paragraph"
  }
]

затем можно легко разобрать на html например

<body>
 <div>
  <p>hello</p>
  <p>universe</p>
 </div>
 <div>
  <h1>Heading 1</h1>
  <p>another paragraph</p>
 </div>
</body>

Я могу видеть рассуждения за вопрос, но как он стоит...Я бы ему не доверял.

это не определено в стандарт ECMA JSON. И вообще, отсутствие определения в стандарте означает: "не рассчитывайте на то, что это работает одинаково везде."

Если вы игрок," многие " JSON-движки позволят дублировать и просто использовать последнее заданное значение. Это:

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

становится этот:

Object {a: 3, b: 2}

но если вы не игрок,не рассчитывайте на это!

в соответствии с RFC-7159, текущим стандартом для JSON, опубликованным инженерной целевой группой Интернета (IETF), говорится, что "имена внутри объекта должны быть уникальными". Однако, согласно RFC-2119, который определяет терминологию, используемую в документах IETF, слово "должен" фактически означает"... в конкретных обстоятельствах могут существовать веские причины для игнорирования конкретного пункта, но все последствия должны быть поняты и тщательно взвешены, прежде чем выбрать другой курс."Что это по существу означает, что, хотя рекомендуется иметь уникальные ключи, это не обязательно. Мы можем иметь дубликаты ключей в объекте JSON, и он все равно будет действителен.

из практического применения я видел, что значение из последнего ключа считается, когда дубликаты ключей находятся в JSON.

В C#, если вы deserialise к Dictionary<string, string> Он берет последнюю пару:

string json = @"{""a"": ""x"", ""a"": ""y""}";
var d = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
// { "a" : "y" }

если вы попытаетесь deserialise к

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 исключения.

стандарт говорит так:

языки программирования сильно различаются в зависимости от того, поддерживают ли они объекты, и если да, то какие характеристики и ограничения предлагают объекты. Этот модели объектных систем могут быть дико расходящимися и продолжают развиваться. JSON вместо этого предоставляет простую нотацию для выражения коллекции пар имя / значение. Большинство языков программирования имеют некоторые функции для представления таких коллекций, которые могут идти по именам как запись, структура, дикт, карта, хэш или объект.

ошибка в узле.js по крайней мере. Этот код успешно выполняется в узле.js.

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

Comments

    Ничего не найдено.