#!style
.code {
font-family: monospace;
padding: .12em;
display: inline;
background-color: #eee;
}
@theseed-dark-mode {
.code {
background-color: #2d2f34
}
}
1. 개요
주어진 JSON 데이터 내의 특정 요소를 선택하는 쿼리 언어이다.RFC 6901에 RFC 표준으로 등록되어 있다.[1]
2. 문법
JSON이 재귀적인 트리 형태의 자료구조이므로, 각각의 부모 요소에서 자식 요소를 선택하는 탐색을 반복함으로써 특정 요소를 유일하게 선택할 수 있다. 이 각각의 선택자를 reference token, 이를 모은 하나의 경로를 pointer라고 한다.유닉스 경로나 URL과 비슷하게 각 키를 슬래시(/)로 구분한다. 이 때 JSON 키에
/ 문자가 verbatim하게 들어갈 경우를 위해 이스케이프 문자로 ~를 사용해 인코딩한다. 가령 키에 슬래시가 두 번 들어갈 경우 ~1~1로 쓰는 식.| 조합 | 해석 |
~0 | ~ |
~1 | / |
객체의 경우 각각의 reference token은 객체 키에 대응된다. 가령 다음과 같이 하나의 블로그 글을 나타내는 독립 JSON 데이터가 주어졌다고 하자.
#!syntax json
{
"id": "namu-1234",
"title": "JSON 파싱에 대한 고찰",
"author": {
"name": "Sefirot",
"role": "Admin"
},
"metadata": {
"views": 1540,
"published": true
},
"tags": ["parser", "json", "spec"]
}
글의 id를 선택하려면
#!wiki class="code"
/id, 글의 작성자 객체를 전부 선택하려면 #!wiki class="code"
/author를 사용하면 된다. 작성자의 권한을 선택하려면 #!wiki class="code"
/author/role과 같이 경로를 계속 이어 선택하면 된다.배열의 경우 각 원소를 인덱스를 사용해 선택하면 된다. 여기서 당연히 인덱스는
0부터 시작한다. 가령 #!wiki class="code"
/tags/0은 "parser"를 선택하고, #!wiki class="code"
/tags/1은 "json"을, #!wiki class="code"
/tags/2는 "spec"을 선택한다.배열의 특수한 선택자로
-이 있는데, -는 배열의 현재 가장 마지막 원소의 다음 인덱스가 들어갈 자리를 선택한다. 트리의 경우 최우단 leaf의 오른쪽 sibiling 자리를 선택한다고 생각하면 된다. 즉 현재는 존재하지 않는 자리를 선택한다는 것인데, 무슨 쓸모가 있나 싶지만 JSON Pointer를 쓰기(write) 동작으로 사용하거나 JSON Patch 등 추가적인 표준과 같이 사용해 JSON 데이터를 조작할 때 유용하다. 앞선 예시의 경우 #!wiki class="code"
/tags/2에 "tutorial" 값을 쓰면 기존 태그 "spec"이 대체되어 버리지만, #!wiki class="code"
/tags/-에 쓰면 새 태그가 배열에 추가되는 식이다.JSON 데이터가 주어졌을 때, 각 pointer는 항상 특정 요소를 이미 선택하고 있다. 기본적으로 이는 루트 요소(전체 JSON 데이터)이며, 따라서 어떤 reference token도 주어지지 않으면 루트 요소를 선택할 수 있다. 주의할 점은, 슬래시를 넣는 순간 reference token으로 인식되기에 어떤 reference token도 주지 않으려면 pointer로 공문자열(빈 문자열,
"")을 주어야 한다. #!wiki class="code"
/처럼 쓰면 빈 문자열("")을 키로 가지는 reference token을 하나 준 것과 같다. 가령 이런 문서가 주어졌을 때#!syntax json
{
"": "a"
}
""(빈 문자열)은 전체 문서 { "": "a" } 를, #!wiki class="code"
/는 "a"를 선택한다.[1] P. C. Bryan, K. Zyp, and M. Nottingham, “JavaScript Object Notation (JSON) Pointer.” RFC Editor, Apr. 2013. doi: 10.17487/RFC6901.