여전히 XML 쓰는 공공 API, JSON 변환법

공공데이터 포털이나 오래된 사내 시스템의 API 문서를 열어봤는데 응답 예시가 JSON이 아니라 XML로 되어 있어서 당황한 적이 있을 것입니다. 요즘 새로 만드는 API는 거의 다 JSON을 쓰는데, 왜 이런 시스템만 XML을 고집하는지 이해하기 어렵습니다. 이 글은 그 이유와, 받은 XML을 다루기 쉬운 JSON으로 바꾸는 방법을 정리합니다.
요약 ① 공공기관·구버전 시스템이 XML을 쓰는 이유는 SOAP·전자정부 표준프레임워크처럼 XML이 표준이던 시절에 설계된 구조를 그대로 쓰고 있기 때문입니다 ② XML의 속성(attribute)은 JSON에서 "@속성명" 키로, 태그와 나란히 있던 텍스트는 "#text" 키로 각각 따로 표현됩니다 ③ 같은 이름의 요소가 한 번만 나오면 객체, 두 번 이상 나오면 배열로 바뀌므로 겉모습만 보고는 값이 몇 개인지 알기 어렵습니다
왜 아직도 XML로 응답하는 API가 있을까
XML이 웹 API의 사실상 표준이던 시절이 있었습니다. 2000년대 초중반 SOAP 기반 웹서비스가 기업·공공기관 시스템의 기본 통신 방식이었고, 이때 설계된 시스템은 지금도 그 구조를 그대로 쓰고 있습니다.
국내 공공기관 시스템 상당수는 전자정부 표준프레임워크를 기반으로 만들어졌습니다. 이 표준이 자리 잡은 시기가 XML·SOAP 방식이 주류였던 때라, 이후 JSON이 대중화된 뒤에도 기존 시스템을 뜯어고치기보다는 XML 응답 구조를 그대로 유지한 채 운영되는 경우가 많습니다.
공공데이터포털에서 내려받는 오픈 API도 비슷합니다. 요청 파라미터에 응답 형식을 지정하지 않으면 XML을 기본값으로 내려주는 API가 여전히 남아 있고, JSON은 별도 파라미터를 추가해야 받을 수 있는 경우가 흔합니다.
시스템을 완전히 새로 설계하지 않는 한 응답 형식만 따로 바꾸기는 쉽지 않습니다. 그 결과 요청하는 쪽에서 XML을 받아 직접 JSON으로 바꿔 쓰는 게 현실적인 대응입니다.
XML을 JSON으로 바꾸는 방법 — 속성과 반복 태그부터 정리하기
XML을 JSON으로 옮길 때 적용되는 규칙은 정해져 있습니다. 책 정보를 담은 XML 문서 하나로 예를 들어보겠습니다. 최상위에 book이라는 요소가 있고 id=1이라는 속성이 붙어 있으며, 그 안에 title, price 요소가 하나씩, tags 요소가 두 번 들어 있다고 하겠습니다.
XML → JSON 변환 규칙 3가지
규칙 1 — 요소 이름은 그대로 키가 됩니다. title, price처럼 자식이 없는 요소는 이름을 키로, 안에 든 텍스트를 값으로 그대로 옮깁니다.
규칙 2 — 속성은 원래 값과 섞이지 않고 "@속성명" 키로 따로 분리됩니다. book의 id 속성은 "@id" 키에 담기고, 텍스트가 함께 있는 요소라면 그 텍스트는 "#text" 키에 따로 담깁니다.
규칙 3 — 같은 이름의 요소가 형제로 여러 번 나오면 배열이 됩니다. tags 요소가 두 번 나왔으므로 값은 SEO와 블로그를 담은 배열이 되고, 한 번만 있었다면 배열이 아니라 문자열 값 하나로 바뀝니다.
세 규칙을 그대로 적용하면 book 키 안에 @id는 "1", title은 "자동화의 정석", price는 "18000", tags는 SEO와 블로그를 담은 배열이 들어간 JSON이 나옵니다.
JSON → XML로 되돌릴 때
객체는 자식 요소로 중첩되고, 배열은 같은 이름의 요소를 값 개수만큼 반복해서 나열합니다. 이때 JSON 전체를 감쌀 최상위 요소 이름이 필요한데, book처럼 키가 하나뿐이어도 그 키가 그대로 최상위 태그가 되지 않고 지정한 루트 요소 이름 아래에 한 번 더 감싸인 형태로 나옵니다.
규칙 자체는 어렵지 않지만, 요소가 중첩되고 속성과 반복 요소가 섞이면 손으로 옮기다 어디서 배열로 바뀌어야 하는지 놓치기 쉽습니다. 특히 같은 요소가 몇 번 나오는지는 원본이 길어질수록 눈으로 세기 어려워집니다.
저희 도구로 확인하기. 변환 방향을 탭으로 고르고 원본을 붙여넣으면 속성과 반복 요소 처리까지 규칙대로 적용된 결과를 바로 확인할 수 있습니다.
무료 · 가입 불필요 · 브라우저에서 바로 JSON ↔ XML 변환

자주 막히는 지점
| 상황 | 왜 그런지 |
|---|---|
| 요소에 속성이 붙어 있음 | 속성은 텍스트 값과 섞이지 않고 "@속성명" 키로 따로 분리됩니다 |
| 같은 요소가 한 번만 vs 여러 번 나옴 | 한 번이면 단일 값, 두 번 이상이면 배열로 바뀌어 이후 처리 코드가 달라져야 합니다 |
| JSON을 XML로 바꿀 때 | 원본 최상위 키가 그대로 태그가 되지 않고 지정한 루트 요소 이름 아래에 한 번 더 감싸입니다 |
| 값이 비어 있는 객체·배열 | 닫는 태그 없이 이름만 쓰는 자기닫힘 형태로 표시되어 빈 값인지 헷갈릴 수 있습니다 |
표에 정리된 상황은 결국 "속성이 있는가"와 "같은 요소가 반복되는가" 두 가지로 좁혀집니다. XML을 볼 때 이 두 가지부터 확인하면 변환 결과를 예측하기 쉬워집니다.
정리
공공기관·구버전 시스템이 아직 XML로 응답하는 이유는 SOAP·전자정부 표준프레임워크처럼 XML이 표준이던 시절에 설계된 구조를 그대로 유지하고 있기 때문입니다. 시스템 자체를 새로 짜지 않는 한, 요청하는 쪽에서 XML을 받아 JSON으로 바꿔 쓰는 편이 현실적입니다.
변환 규칙은 속성을 "@속성명" 키로 분리하고, 반복되는 요소를 배열로 묶는 두 가지가 핵심입니다. 이 규칙만 알면 손으로도 변환할 수 있지만, 요소가 많아질수록 반복 여부를 눈으로 세는 일이 번거로워집니다.
무료 · 가입 불필요 · 브라우저에서 바로 JSON ↔ XML 변환
자주 묻는 질문
XML 속성은 JSON에서 어떻게 표시되나요?
속성은 원래 텍스트 값과 구분하기 위해 "@속성명" 형태의 별도 키로 들어갑니다. 속성과 텍스트가 함께 있는 요소라면 텍스트는 "#text" 키에 따로 담겨, 속성과 텍스트가 한 값으로 뒤섞이지 않습니다.
같은 태그가 여러 번 나오면 항상 배열이 되나요?
같은 이름의 요소가 형제로 두 번 이상 나오면 배열로 바뀝니다. 한 번만 나오면 배열이 아니라 단일 값(문자열 또는 객체)으로 처리되므로, 코드에서 이 값을 다룰 때는 배열인지 아닌지 먼저 확인해야 합니다.
JSON을 XML로 바꿀 때 루트 요소 이름은 왜 필요한가요?
XML 문서는 하나의 최상위 요소로 시작해야 합니다. 원본 JSON에 키가 하나뿐이어도 그 키가 그대로 최상위 태그가 되지 않고, 지정한 루트 요소 이름이 감싸는 바깥쪽 태그가 되며 원래 있던 키는 그 안의 자식 요소로 들어갑니다.
