JSON 경로 찾기: JSONPath 완벽 가이드와 실용 도구
JSON 데이터에서 원하는 값의 경로를 찾고 JSONPath를 마스터하세요. 실용적인 예제와 도구를 통해 완벽히 배워봅니다.
Big JSON Team
• Technical WriterExpert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.
# JSON 경로 찾기: JSONPath 완벽 가이드와 실용 도구
복잡한 JSON 데이터에서 특정 값을 찾고 접근하는 것은 개발자의 일상입니다. JSONPath를 마스터하여 효율적으로 데이터를 다루는 방법을 배워보세요.
JSON 경로란?
JSON 경로는 JSON 데이터 구조 내에서 특정 값의 위치를 나타내는 표기법입니다.
간단한 예제
{
"user": {
"name": "홍길동",
"address": {
"city": "서울"
}
}
}
경로 표기:
user.name→ "홍길동"user.address.city→ "서울"
JSONPath란?
JSONPath는 XPath와 유사한 JSON용 쿼리 언어입니다. JSON 데이터를 쿼리하고 추출할 수 있습니다.
기본 연산자
| 연산자 | 설명 | 예제 |
|-------|------|------|
| $ | 루트 객체 | $ |
| @ | 현재 객체 | @.price |
| . | 자식 접근 | $.user.name |
| [] | 배열 접근 | $[0] |
| .. | 재귀 하강 | $..price |
| | 와일드카드 | $.users[] |
| [,] | 다중 선택 | $[0,2,5] |
| [:] | 배열 슬라이스 | $[0:5] |
| ?() | 필터 | $[?(@.price < 10)] |
기본 경로 표기법
객체 접근
{
"name": "홍길동",
"age": 30,
"email": "hong@example.com"
}
경로:
$.name→ "홍길동"$.age→ 30$.email→ "hong@example.com"
중첩 객체
{
"user": {
"profile": {
"name": "홍길동",
"contact": {
"email": "hong@example.com"
}
}
}
}
경로:
$.user.profile.name→ "홍길동"$.user.profile.contact.email→ "hong@example.com"
배열 접근
{
"users": ["홍길동", "김철수", "이영희"]
}
경로:
$.users[0]→ "홍길동"$.users[1]→ "김철수"$.users[2]→ "이영희"$.users[-1]→ "이영희" (마지막)
객체 배열
{
"users": [
{ "name": "홍길동", "age": 30 },
{ "name": "김철수", "age": 25 }
]
}
경로:
$.users[0].name→ "홍길동"$.users[1].age→ 25$.users[].name→ ["홍길동", "김철수"]
고급 JSONPath 표현식
와일드카드 ()
모든 요소 선택:
{
"store": {
"book": [
{ "title": "책1", "price": 10 },
{ "title": "책2", "price": 15 }
]
}
}
경로:
$.store.book[].title→ ["책1", "책2"]$.store.book[].price→ [10, 15]
재귀 하강 (..)
모든 레벨에서 검색:
{
"company": {
"department": {
"name": "개발팀",
"team": {
"name": "프론트엔드"
}
}
}
}
경로:
$..name→ ["개발팀", "프론트엔드"]
배열 슬라이스
{
"numbers": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}
경로:
$.numbers[0:3]→ [0, 1, 2]$.numbers[2:5]→ [2, 3, 4]$.numbers[-3:]→ [7, 8, 9]$.numbers[::2]→ [0, 2, 4, 6, 8] (짝수 인덱스)
다중 선택
{
"items": ["a", "b", "c", "d", "e"]
}
경로:
$.items[0,2,4]→ ["a", "c", "e"]$.items[1,3]→ ["b", "d"]
필터 표현식
{
"products": [
{ "name": "노트북", "price": 1500000, "stock": 5 },
{ "name": "마우스", "price": 30000, "stock": 50 },
{ "name": "키보드", "price": 80000, "stock": 0 }
]
}
경로:
$.products[?(@.price < 100000)]→ 10만원 미만 제품$.products[?(@.stock > 0)]→ 재고 있는 제품$.products[?(@.name == '마우스')]→ 이름이 "마우스"인 제품
==: 같음!=: 다름<: 작음<=: 작거나 같음>: 큼>=: 크거나 같음=~: 정규식 매치
복합 필터
{
"products": [
{ "name": "노트북", "price": 1500000, "category": "전자" },
{ "name": "마우스", "price": 30000, "category": "전자" },
{ "name": "책", "price": 15000, "category": "도서" }
]
}
경로:
$.products[?(@.price > 20000 && @.category == '전자')]$.products[?(@.price < 50000 || @.category == '도서')]
JavaScript에서 사용하기
jsonpath 라이브러리
npm install jsonpath
기본 사용:
const jp = require('jsonpath');
const data = {
store: {
book: [
{ title: '책1', price: 10, author: '저자1' },
{ title: '책2', price: 15, author: '저자2' },
{ title: '책3', price: 8, author: '저자1' }
]
}
};
// 모든 책 제목
const titles = jp.query(data, '$.store.book[].title');
console.log(titles); // ['책1', '책2', '책3']
// 가격이 10보다 작은 책
const cheap = jp.query(data, '$.store.book[?(@.price < 10)]');
console.log(cheap); // [{ title: '책3', price: 8, author: '저자1' }]
// 특정 저자의 책
const byAuthor = jp.query(data, "$.store.book[?(@.author == '저자1')]");
console.log(byAuthor);
경로 가져오기:
const paths = jp.paths(data, '$.store.book[].title');
console.log(paths);
// [
// ['$', 'store', 'book', 0, 'title'],
// ['$', 'store', 'book', 1, 'title'],
// ['$', 'store', 'book', 2, 'title']
// ]
경로 문자열로:
paths.forEach(path => {
console.log(jp.stringify(path));
});
// $['store']['book'][0]['title']
// $['store']['book'][1]['title']
// $['store']['book'][2]['title']
값 설정:
jp.value(data, '$.store.book[0].price', 12);
console.log(data.store.book[0].price); // 12
노드 정보:
const nodes = jp.nodes(data, '$.store.book[].price');
nodes.forEach(node => {
console.log('경로:', node.path);
console.log('값:', node.value);
});
lodash/get (간단한 경로)
npm install lodash
const _ = require('lodash');
const data = {
user: {
profile: {
name: '홍길동'
}
}
};
// 안전한 접근
const name = _.get(data, 'user.profile.name');
console.log(name); // '홍길동'
// 기본값 제공
const age = _.get(data, 'user.profile.age', 0);
console.log(age); // 0
// 배열 경로
const items = {
users: [
{ name: '홍길동' },
{ name: '김철수' }
]
};
const firstName = _.get(items, 'users[0].name');
console.log(firstName); // '홍길동'
Python에서 사용하기
jsonpath-ng
pip install jsonpath-ng
from jsonpath_ng import parse
data = {
'store': {
'book': [
{'title': '책1', 'price': 10},
{'title': '책2', 'price': 15}
]
}
}
# 경로 파싱
jsonpath_expr = parse('$.store.book[].title')
# 값 찾기
matches = jsonpath_expr.find(data)
for match in matches:
print(f'경로: {match.full_path}')
print(f'값: {match.value}')
# 값만 추출
titles = [match.value for match in matches]
print(titles) # ['책1', '책2']
필터 사용:
from jsonpath_ng.ext import parse
data = {
'products': [
{'name': '노트북', 'price': 1500000},
{'name': '마우스', 'price': 30000}
]
}
# 가격이 100000보다 작은 제품
jsonpath_expr = parse('$.products[?(@.price < 100000)]')
matches = jsonpath_expr.find(data)
for match in matches:
print(match.value)
실용 예제
API 응답에서 데이터 추출
const jp = require('jsonpath');
const apiResponse = {
status: 'success',
data: {
users: [
{
id: 1,
name: '홍길동',
posts: [
{ id: 101, title: '첫 게시물', likes: 10 },
{ id: 102, title: '두번째', likes: 25 }
]
},
{
id: 2,
name: '김철수',
posts: [
{ id: 201, title: '안녕하세요', likes: 5 }
]
}
]
}
};
// 모든 사용자 이름
const names = jp.query(apiResponse, '$.data.users[].name');
console.log('사용자:', names);
// 모든 게시물 제목
const titles = jp.query(apiResponse, '$..posts[].title');
console.log('게시물:', titles);
// 좋아요 10개 이상인 게시물
const popular = jp.query(apiResponse, '$..posts[?(@.likes >= 10)]');
console.log('인기 게시물:', popular);
// 특정 사용자의 게시물
const userPosts = jp.query(
apiResponse,
"$.data.users[?(@.name == '홍길동')].posts[]"
);
console.log('홍길동의 게시물:', userPosts);
설정 파일에서 값 찾기
const config = {
app: {
name: 'MyApp',
version: '1.0.0',
environments: {
development: {
api: 'http://localhost:3000',
debug: true
},
production: {
api: 'https://api.example.com',
debug: false
}
}
},
features: {
authentication: { enabled: true },
notifications: { enabled: false }
}
};
// 모든 API URL
const apis = jp.query(config, '$..api');
console.log('APIs:', apis);
// 활성화된 기능
const enabledFeatures = jp.query(
config,
'$.features[?(@.enabled == true)]'
);
console.log('활성화된 기능:', enabledFeatures);
중첩된 데이터 변환
const data = {
company: {
departments: [
{
name: '개발',
employees: [
{ name: '홍길동', salary: 50000 },
{ name: '김철수', salary: 45000 }
]
},
{
name: '디자인',
employees: [
{ name: '이영희', salary: 48000 }
]
}
]
}
};
// 모든 직원 이름
const employees = jp.query(data, '$..employees[].name');
console.log('직원:', employees);
// 급여 합계
const salaries = jp.query(data, '$..employees[].salary');
const total = salaries.reduce((sum, sal) => sum + sal, 0);
console.log('총 급여:', total);
// 부서별 직원 수
const depts = jp.query(data, '$.company.departments[]');
depts.forEach(dept => {
console.log(${dept.name}: ${dept.employees.length}명);
});
온라인 JSONPath 도구
1. JSON Simplify
JSON Simplify - 한국어 지원 기능:- JSONPath 쿼리
- 경로 자동 생성
- 시각적 트리 뷰
- 값 복사
2. JSONPath Online Evaluator
jsonpath.com 기능:- JSONPath 테스트
- 예제 제공
- 문법 참조
3. JSONPath Finder
jsonpathfinder.com 기능:- 시각적 경로 찾기
- 드래그 앤 드롭
- 경로 복사
도구별 JSONPath 구현 차이
구현별 지원 기능
| 기능 | Goessner | jsonpath-ng | jayway |
|------|----------|-------------|--------|
| 기본 경로 | ✅ | ✅ | ✅ |
| 재귀 하강 | ✅ | ✅ | ✅ |
| 필터 | ✅ | ✅ | ✅ |
| 스크립트 | ❌ | ❌ | ✅ |
| 함수 | ❌ | ❌ | ✅ |
주의사항
일부 고급 기능은 구현마다 다를 수 있습니다. 사용 전에 문서를 확인하세요.
성능 고려사항
1. 재귀 하강 최소화
// 느림
jp.query(data, '$..name');
// 빠름 (정확한 경로)
jp.query(data, '$.users[].name');
2. 필터 최적화
// 느림
jp.query(data, '$..products[?(@.price < 100)]');
// 빠름
jp.query(data, '$.products[?(@.price < 100)]');
3. 캐싱
// 경로 표현식 재사용
const expr = jp.compile('$.users[].name');
// 여러 번 사용
const names1 = expr.query(data1);
const names2 = expr.query(data2);
모범 사례
1. 명확한 경로 사용
// 좋음
'$.users[0].profile.name'
// 나쁨 (너무 모호함)
'$..name'
2. 안전한 접근
// 존재하지 않을 수 있는 경로
const result = jp.query(data, '$.user.profile.name');
const name = result.length > 0 ? result[0] : '기본값';
3. 타입 검증
const prices = jp.query(data, '$.products[*].price');
const validPrices = prices.filter(p => typeof p === 'number');
4. 문서화
// 복잡한 쿼리에 주석 추가
const query = '$.store.book[?(@.price < 10 && @.category == "fiction")]';
// 10달러 미만 소설책 찾기
결론
JSONPath는 복잡한 JSON 데이터를 쿼리하는 강력한 도구입니다. 기본 경로부터 고급 필터까지 마스터하면 데이터 처리가 훨씬 쉬워집니다.
핵심 요약:- ✅ 점 표기법으로 객체 접근
- ✅ 대괄호로 배열 접근
- ✅ 필터로 조건부 선택
- ✅ 재귀 하강으로 깊은 검색
- ✅ 적절한 라이브러리 선택
지금 바로 JSON Simplify에서 JSON 경로를 찾아보세요!
관련 글
온라인 JSON 도구: 2026년 최고의 무료 도구 TOP 15
JSON 작업을 위한 최고의 온라인 도구를 발견하세요. 포맷터, 검증기, 에디터, 변환기 등 - 모든 무료 도구를 한 곳에서 비교합니다.
대용량 JSON 다루기: 성능 최적화와 실용 기법
기가바이트 크기의 JSON 파일을 효율적으로 처리하는 방법을 배워보세요. 스트리밍, 청크 처리, 메모리 최적화까지 완벽 정리.
고급 JSON 구조: 복잡한 데이터 모델링 마스터하기
복잡한 데이터 구조를 JSON으로 효과적으로 표현하는 방법을 배워보세요. 그래프, 트리, 다형성, 참조 처리까지 완벽 정리.