유효한 최소 JSON은 무엇입니까?


174

JSON 설명 http://json.org/을 주의 깊게 읽었 지만 간단한 질문에 대한 답을 모르겠습니다. 유효한 최소 JSON은 무엇입니까?

  • "string" 문자열이 유효한 JSON입니까?
  • 42 간단한 숫자가 유효한 JSON입니까?
  • true 부울 값이 유효한 JSON입니까?
  • {} 빈 객체가 유효한 JSON입니까?
  • [] 빈 배열이 유효한 JSON입니까?

12
jsonlint.com 에서 테스트 했는데 마지막 두 개는 유효하지만 다른 두 개는 유효하지 않습니다.
ironcito

1
일부 JSON 파서는 배열이나 객체를 기대합니다. 그들은 단지 숫자 또는 문자열에 대해 불평합니다.
akonsu

3
현재로서는 유효합니다
Brian Colavito


짧은 답변-{}
Tukaram Bhosale

답변:


156

글을 쓰는 시점에서 JSON은 RFC4627 에서만 설명되었습니다 . JSON 텍스트를 직렬화 된 객체 또는 배열로 설명합니다 ( "2"시작 부분).

이 방법 만을 {}[]파서 그 표준을 준수 stringifiers에서 유효, 전체 JSON 문자열입니다.

그러나 ECMA-404의 도입으로 변경되었으며 업데이트 된 조언 은 여기에서 읽을 수 있습니다 . 또한 이 문제에 대한 블로그 게시물작성했습니다 .


그러나 문제를 더 혼란스럽게하기 위해 웹 브라우저에서 사용할 수 있는 JSON객체 (예 : JSON.parse()JSON.stringify()) 가 ES5 에서 표준화되어 수용 가능한 JSON 텍스트를 다음과 같이 명확하게 정의합니다.

이 사양에 사용 된 JSON 교환 형식은 RFC 4627에 설명 된 형식과 정확히 일치하며 다음 두 가지 예외가 있습니다.

  • ECMAScript JSON 문법의 최상위 JSONText 생성은 RFC 4627에 지정된 JSONObject 또는 JSONArray로 제한되지 않고 모든 JSONValue로 구성 될 수 있습니다.

  • 도청

이는 JSON 객체가 기술적으로 RFC 4627을 준수하더라도 모든 JSON 값 (문자열, null 및 숫자 포함)이 JSON 객체에 의해 수락됨을 의미합니다.

따라서 JSON.stringify(5)RFC4627을 준수하지만 위에 나열된 특정 예외는없는 다른 파서에서 거부되는을 통해 준수 브라우저에서 숫자 를 문자열화할 수 있습니다. 예를 들어, Ruby 는 객체와 배열 root로 받아들이는 하나의 예인 것 같습니다 . 반면에 PHP 는 특히 "스칼라 형식과 NULL도 인코딩 및 디코딩합니다" 라는 예외추가합니다 .


@ amdorra : 당신이 그것을보고있는 곳을 더 구체적으로 지정할 수 있습니까?
Matt

5
JSON은 명사가 아니므로 "JSON"은 의미가 없습니다. "JSON 값"은 "JSON 값"이지만 파서는 종종 해당 RFC에 정의 된 "JSON 텍스트"를 기대합니다.
IMSoP

2
내 나쁜 그때 내 대답을 삭제합니다
amdorra

1
@jmoreno 귀하의 의견을 명확하게 설명해 주시겠습니까? 당신이 말하는 true, false또는 null혼자하는 것은 올바른 JSON 텍스트입니까? 여기에 다른 답변 / 의견 대부분과 모순되기 때문에 출처를 인용 해 주시겠습니까?
로렌스 존스턴

2
@jmoreno : 확실히 2 "JSON 텍스트는 직렬화 된 객체 또는 배열입니다." 그 반대? JSON Lint는 또한 비 배열 또는 객체가 유효하다고 생각하지 않습니다. 문자열이 유효한 JSON 리터럴인지에 대한 논쟁은 없습니다. 이것은 문자열 자체가 유효한지 여부입니다.
Matt

42

인터넷에서 JSON 표준으로 간주 될 수있는 문서가 4 개 이상 있습니다. 참조 된 RFC는 모두 MIME 유형을 설명합니다 application/json. 다음은 최상위 값과 객체 또는 배열 이외의 항목이 최상위에 허용되는지 여부에 대한 설명입니다.

RFC-4627 : 아니오

JSON 텍스트는 일련의 토큰입니다. 토큰 세트에는 6 개의 구조 문자, 문자열, 숫자 및 3 개의 리터럴 이름이 포함됩니다.

JSON 텍스트는 직렬화 된 객체 또는 배열입니다.

JSON 텍스트 = 객체 / 배열

RFC-4627은 "제안 된 표준"과 반대로 "정보"로 표시되었으며, RFC-7159에 의해 폐기되었으며, RFC-7159 는 RFC-8259에 의해 폐기되었습니다.

RFC-8259 : 예.

JSON 텍스트는 일련의 토큰입니다. 토큰 세트에는 6 개의 구조 문자, 문자열, 숫자 및 3 개의 리터럴 이름이 포함됩니다.

JSON 텍스트는 직렬화 된 값입니다. JSON의 특정 이전 사양에서는 JSON 텍스트를 객체 또는 배열로 제한했습니다. JSON 텍스트가 호출되는 객체 또는 배열 만 생성하는 구현은 모든 구현에서이를 일치하는 JSON 텍스트로 허용한다는 의미에서 상호 운용 가능합니다.

JSON 텍스트 = WS 값 WS

RFC-8259는 2017 년 12 월 날짜이며 "인터넷 표준"으로 표시되어 있습니다.

ECMA-262 : 예.

JSON 구문 문법은 JSON 어휘 문법에 의해 정의 된 토큰으로 유효한 JSON 텍스트를 정의합니다. 문법의 목표 기호는 JSONText입니다.

구문 JSONText :

JSONValue

JSONValue :

JSONNullLiteral

JSONBooleanLiteral

JSONObject

JSONArray

JSONString

JSONNumber

ECMA-404 : 예.

JSON 텍스트는 JSON 값 문법을 따르는 유니 코드 코드 포인트로 구성된 일련의 토큰입니다. 토큰 세트에는 6 개의 구조 토큰, 문자열, 숫자 및 3 개의 리터럴 이름 토큰이 포함됩니다.


10

RFC 4627 (RFC 7159에 의해 2014 년 3 월 폐기 됨)의 이전 정의에 따르면 ,이 값은 모두 유효한 "JSON 값"이지만 마지막 두 개만이 완전한 "JSON 텍스트"를 구성합니다.

JSON 텍스트는 직렬화 된 객체 또는 배열입니다.

사용 된 구문 분석기에 따라 고독한 "JSON 값"이 허용 될 수 있습니다. 예를 들어 ( "JSON 값"대 "JSON 텍스트"용어를 고수) :

  • JSON.parse()지금은 최신 브라우저에서 표준화 기능은 "JSON 값을"받아
  • PHP 함수 json_decode는 전체 "JSON 텍스트"만 허용하는 버전 5.2.0에서 도입되었지만 버전 5.2.1에서 "JSON 값"을 허용하도록 수정되었습니다.
  • 파이썬 json.loads이 매뉴얼 페이지의 예제 따라 "JSON 값"을 받아들입니다 .
  • 검증 인 http://jsonlint.com "JSON 텍스트"가 필요합니다.
  • Ruby JSON 모듈은 전체 "JSON 텍스트"만 수락합니다 (적어도 의견에 따르면 매뉴얼 페이지 에 ).

"XML 문서"와 "XML 조각"의 구별과 비슷하지만 기술적 <foo />으로는 잘 구성된 XML 문서 <?xml version="1.0" ?><foo />이지만 (로 작성하는 것이 좋지만 주석에서 지적한 바와 같이 <?xml선언은 기술적으로 선택 사항입니다. ).


XML 문서는 선택적 XML 선언없이 완전히 유효하기 때문에 XML 비교가 부적절 할 수 있습니다. w3.org/TR/xml/#sec-well-formed
Gunther

@ Gunther Ah, 예, 그것은 매우 권장되지만 기술적으로 선택 사항이라는 것을 잊었습니다.
IMSoP

@ 건더 : nitpick : <foo />잘 구성된 XML 문서이지만 유효한 문서는 아닙니다 . (그러나 동일합니다 <?xml version="1.0" ?><foo />.)
ruakh

@ruakh 흥미롭게도, 여기서 정의는 XML이 DTD에 대해서만 "유효"할 수 있음을 의미합니다. 이는 DTD가 실제로 거의 작성되고 선언되지 않기 때문에 XML 문서가 거의 없다는 것을 의미합니다 (XSD 또는 RelaxNG와 같은 스키마 정의 형식과 비교). . 외부 스키마에 대해 참조하지 않고 유효 할 수 있다면 특정 스키마에 대해 유효 <foo /> 하거나 유효 하지 않을 수 있기 때문에 확인 했지만 그 표준이 아닙니다.
IMSoP

4

ecma 사양은 참조에 유용 할 수 있습니다.

http://www.ecma-international.org/ecma-262/5.1/

구문 분석 함수는 JSON 텍스트 (JSON 형식 문자열)를 구문 분석하고 ECMAScript 값을 생성합니다. JSON 형식은 제한된 형식의 ECMAScript 리터럴입니다. JSON 객체는 ECMAScript 객체로 구현됩니다. JSON 배열은 ECMAScript 배열로 실현됩니다. JSON 문자열, 숫자, 부울 및 널은 ECMAScript 문자열, 숫자, 부울 및 널로 실현됩니다. JSON은 공백보다 제한된 공백 문자 집합을 사용하며 이스케이프 시퀀스를 사용하지 않고 유니 코드 코드 포인트 U + 2028 및 U + 2029가 JSONString 리터럴에 직접 표시되도록합니다. 파싱 ​​과정은 JSON 문법에 의해 제한되는 11.1.4 및 11.1.5와 유사합니다.

JSON.parse("string"); // SyntaxError: Unexpected token s
JSON.parse(43); // 43
JSON.parse("43"); // 43
JSON.parse(true); // true
JSON.parse("true"); // true
JSON.parse(false);
JSON.parse("false");
JSON.parse("trueee"); // SyntaxError: Unexpected token e
JSON.parse("{}"); // {}
JSON.parse("[]"); // []

4
유용한 참조이지만 형식 자체가 아닌 특정 JSON 파서 (ECMAScript 표준에 정의 된 파서)의 사양입니다. json.org 는 JSON이 "완전히 언어에 독립적"이라고 명시하고 있으므로 올바른 파서는 없습니다.
IMSoP

1
JavaScript / ECMAScipt는 JSON 및 그 사용자에게는 영감을 주지만 "홈"은 아닙니다. JSON은 (이전 버전의) ECMAScript의 객체 리터럴 표기법에서 파생되었지만 동일하지는 않습니다. JSON.parse그런 다음 이 기능은 Crockford의 문법과 RFC에 따라 ECMAScript 표준의 이후 버전에 추가되었습니다.
IMSoP

4
당신이해야 할 일JSON.parse("\"string\"");
ericbn

4

JSON은 JavaScript Object Notation의 약어입니다. 단지 {}[]자바 스크립트 객체를 정의합니다. 다른 예는 가치 리터럴입니다. Javascript에는 해당 값으로 작업하기위한 객체 유형이 있지만 표현식 "string"은 객체가 아닌 리터럴 값의 소스 코드 표현입니다.

JSON은 Javascript가 아닙니다. 데이터를 나타내는 표기법입니다. 매우 간단하고 제한된 구조입니다. JSON 데이터는 {},:[]문자를 사용하여 구성됩니다 . 해당 구조 내에서만 리터럴 값을 사용할 수 있습니다.

서버가 객체 설명 또는 리터럴 값으로 응답하는 것이 완벽하게 유효합니다. 모든 JSON 파서는 리터럴 값만 처리하고 하나의 값만 처리하도록 처리해야합니다. JSON은 한 번에 하나의 객체 만 나타낼 수 있습니다. 따라서 서버가 둘 이상의 값을 반환하려면이를 객체 또는 배열로 구성해야합니다.


1
나는이 방향에서 대답에 접근하는 것이 명확하게하는 것 이상으로 생각합니다. 이름의 기원은 표준의 세부 사항과 관련이 없으며 JavaScript에서 사용 가능한 유형은 JSON의 유형에 영감을 줄 수 있지만 요구 사항은 없습니다. 일치합니다. json.org에 소개 된 "JSON은 완전히 언어에 독립적 인 텍스트 형식"
IMSoP

@IMSoP 전적으로 동의합니다. Javascript 유형을 JSON과 혼합했지만 올바르지 않습니다. 답변을 업데이트하겠습니다.
Reactgular

2

예, 예, 네, 네 모두 유효한 JSON 값 리터럴입니다.

그러나 공식 RFC 4627 은 다음과 같이 말합니다.

JSON 텍스트는 직렬화 된 객체 또는 배열입니다.

따라서 전체 "파일"은 가장 바깥 쪽 구조 인 개체 또는 배열로 구성되어야하며 물론 비어있을 수 있습니다. 그러나 많은 JSON 파서는 입력에 기본 값을 허용합니다.


-1
var x;
JSON.stringify(x); // will output "{}"

그래서 당신의 대답은 "{}"빈 객체를 나타냅니다.


FWIW, Chrome에서는 undefined"{}"이 아닌을 제공합니다 .
Matt

-2

json.org 페이지 에 제공된 철도 다이어그램을 따르십시오 . [] 및 {}은 가능한 최소 유효한 JSON 객체입니다. 답은 []와 {}입니다.


3
FSM이 아니라 문법입니다. 그리고 어떤 생산이 시작 규칙인지는 나타내지 않습니다. 시작 규칙이 array맞았고 object귀하가 옳았지만 value시작이 될 것으로 예상 되는 것이 합리적 입니다.

그래도 상당히 간단 해 보입니다. Douglas Crockford는이를 부르며 항상 왼쪽에서 시작하여 오른쪽 트랙을 따라갑니다. 가장 작은 트랙은 최소한의 유효한 JSON을 제공합니다.
Hrishi

2
내가 반대하는 특정 문법 규칙에 대한 해석은 아닙니다. 두 가지 규칙을 선택하고 하나는 다른 규칙이 아닌 규칙에서만 시작할 수 있다고 가정합니다. 당신이 보면 values대신 (또는 이외에) 제 규 arrayobject규칙은 다음 독립 숫자와 문자열이 유효한 JSON 문서입니다.

-1. 먼저 @delnan이 지적했듯이 json.org의 다이어그램에는 완전한 JSON 텍스트가 객체 또는 배열이어야 함을 제안하지 않습니다. json.org의 내용을 기반으로하지 않고 임의로이 두 가지를 선택했습니다. 둘째, 용어에 대한 nitpicking : [], 문제에 대해 의견을 모은 모든 사양에서 유효한 JSON 텍스트는 JSON 개체가 아니기 때문에 "유효한 JSON 개체"가 아닙니다. JSON의 "개체"는 구체적으로 {}표기법을 나타냅니다 . JSON 배열은 JSON 객체가 아닙니다.
Mark Amery
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.