XML → JSON 변환 도구
XML → JSON 변환이란?
XML → JSON 변환은 XML(Extensible Markup Language) 데이터를 JSON(JavaScript Object Notation) 형식으로 변환하는 과정입니다. 레거시 시스템 현대화, JSON을 기대하는 REST API 연동, 더 간결하고 파싱하기 쉬운 데이터 형식이 필요할 때 유용합니다. 속성, 네임스페이스, 빈 요소, 반복 노드, 혼합 텍스트는 변환 규칙에 따라 JSON 구조가 달라집니다. 실제 연동 전에는 예외 데이터까지 넣어 결과를 검증해야 합니다.
사용 방법
사용 방법
- 왼쪽 입력 상자에 XML 데이터를 붙여넣거나 입력하세요
- 들여쓰기 크기를 선택하세요 (2칸, 4칸 또는 탭)
- 변환된 JSON이 오른쪽에 구문 강조와 함께 표시됩니다
- 변환 결과를 검토하고 XML 오류를 수정하세요
- '복사' 또는 '다운로드'를 클릭하여 결과를 저장하세요
데이터 구조 참고사항
- XML 속성, 반복 노드, 네임스페이스, 혼합 텍스트는 JSON에 여러 방식으로 매핑될 수 있으므로 사용 전에 결과를 확인하세요.
- API 마이그레이션 시 샘플 변환 하나만 믿지 말고 필드 매핑 규칙을 정의하세요.
활용 사례
기술 원리
변환은 브라우저 내장 XML 파서에서 시작됩니다. `new DOMParser().parseFromString(xmlString, 'application/xml')`은 W3C DOM Level 3 Core를 따르는 `Document`를 반환하고, XML 1.0(제5판)에 대해 적합성을 검증하며, `Element`, `Attr`, `Text`, `CDATASection`, `Comment` 노드의 트리로 결과를 노출합니다. 입력이 잘못된 형태일 때 파서는 예외를 던지지 않습니다. 대신 위치와 이유를 포함하는 `<parsererror>`를 루트 요소로 하는 문서를 반환하므로, 변환기는 먼저 `doc.querySelector('parsererror')`를 확인하고 부분 JSON을 생성하는 대신 해당 메시지를 표시합니다. 트리-JSON 매핑은 깊이 우선으로 문서를 순회하며 Badgerfish 스타일 관례를 따릅니다. 각 요소는 로컬 이름이 키인 속성이 되고, 자식 요소는 중첩 객체가 되며, 요소 속성은 `@` 접두사로 평탄화됩니다(예: `<user id="7">` → `{ "user": { "@id": "7" } }`). 자식 요소와 함께 있는 텍스트 콘텐츠는 `#text`에 저장됩니다. 같은 이름의 반복된 형제 요소는 JSON 배열로 접힙니다: 두 개의 `<item>` 노드는 `"item": [ ... ]`이 되지만, 단일 `<item>`은 일반 객체로 유지됩니다. 이것이 바로 잘 알려진 "단일 vs 다수" 모호성입니다. XML은 요소 목록과 스칼라 값을 구분할 수 없지만 JSON은 `"item": {...}`와 `"item": [{...}]`를 다른 구조로 취급하기 때문입니다. 일부 XML 기능은 깔끔한 JSON 등가물이 없으며 의도적으로 손실됩니다. 요소 순서는 XML에서 보존되지만 모든 소비자에서 JSON 객체 키 순서가 보장되지는 않습니다(ES2015는 문자열 키에 대해 삽입 순서를 지정하지만 JSON Schema 같은 스키마는 이를 제약하지 않습니다). `<p>Hello <b>world</b>!</p>` 같은 혼합 콘텐츠는 텍스트와 요소가 혼재되어 단순 키-값 모델로 라운드트립할 수 없습니다. Clark 표기법의 XML 네임스페이스(`{http://example.com/ns}user`)는 로컬 이름 `user`로 축소되므로 같은 이름의 관련 없는 요소와 충돌할 수 있습니다. `<![CDATA[<raw>]]>` 같은 CDATA 블록은 일반 텍스트로 해제됩니다. 처리 지시문(`<?xml-stylesheet ...?>`), 주석(`<!-- ... -->`), XML 선언은 JSON에 해당 구문이 없으므로 폐기됩니다. 들여쓰기는 `JSON.stringify(value, null, indent)`로 적용되며 2칸, 4칸 또는 `'\t'`를 사용합니다.
- 파서: W3C DOM Level 3 Core에 따른 `new DOMParser().parseFromString(xml, 'application/xml')`; 오류는 던져진 예외가 아닌 `<parsererror>` 루트 요소로 표면화됩니다.
- 매핑 관례: Badgerfish 스타일로 속성에 `@attr`, 혼합 텍스트에 `#text`, 자식에 요소 로컬 이름 사용. Parker는 속성을 삭제하고, Spark는 `$`에 보존합니다.
- 같은 이름의 반복된 자식은 JSON 배열로 접힙니다. 단일 자식은 객체로 유지됩니다. 고전적인 "단일 vs 다수" 모호성은 XML 측에서 해결할 수 없습니다.
- 손실 기능: 속성(`@` 접두사 없이), 네임스페이스(`xmlns:foo`), 처리 지시문, 주석, XML 선언, CDATA 래퍼.
- 혼합 콘텐츠(`<p>Hello <b>world</b>!</p>`)는 키-값 JSON으로 라운드트립할 수 없습니다. 키 순서를 보존하지 않는 소비자에서는 요소 순서가 손실될 수 있습니다.
- 숫자/불리언 강제 변환은 의도적 선택입니다: `<age>30</age>`는 `30`(숫자) 또는 `"30"`(문자열)이 될 수 있습니다. 선행 0(`007`)은 문자열로 유지해야 합니다.
- 출력 포맷팅은 `JSON.stringify(value, null, indent)`를 사용하며 들여쓰기는 2칸, 4칸 또는 `'\t'`입니다. 결과는 BOM 없는 UTF-8입니다.
예시
단순 요소
<root>
<name>John</name>
</root>
→
{"root": {"name": "John"}}반복 요소
<root>
<item>A</item>
<item>B</item>
</root>
→
{"root": {"item": ["A", "B"]}}중첩 구조
<root>
<user>
<name>John</name>
<age>30</age>
</user>
</root>
→
{"root": {"user": {"name": "John", "age": 30}}}자주 묻는 질문
XML 요소는 JSON으로 어떻게 매핑되나요?
각 요소는 JSON 프로퍼티가 되며 값은 해당 요소의 내용(문자열 또는 중첩 객체)이 됩니다. 같은 이름이 반복되는 요소는 배열이 됩니다. 속성은 보통 '@' 접두사가 붙거나 '$' 같은 특수 키 아래에 저장되며, 정확한 규칙은 페이지마다 설정 가능한 경우가 많습니다.
XML→JSON 변환에서 정보가 일부 손실되는 이유는 무엇인가요?
XML은 요소, 속성, 텍스트 내용, 혼합 내용(텍스트와 요소가 섞인 경우), 네임스페이스, 처리 명령, 주석을 모두 구분합니다. 반면 JSON은 객체, 배열, 문자열, 숫자, 불리언, null만 표현합니다. 더 풍부한 XML 트리를 JSON에 매핑하면 순서나 요소/속성 구분 같은 정보가 사라집니다.
혼합 내용(텍스트 + 자식 요소)은 어떻게 처리되나요?
Hello world!
같은 구조는 깔끔한 JSON 표현이 없습니다. 보통 '#text'나 '$' 같은 특수 키로 떠 있는 텍스트를 담지만, 텍스트와 요소 사이의 순서가 항상 보존되지는 않습니다. 라운드트립이 필요하다면 혼합 내용은 피하세요.XML 네임스페이스는 어떻게 다뤄지나요?
접두사가 있는 요소(<ns:foo>)는 'ns:foo' 같은 문자열 키가 되거나 ns/local-name 프로퍼티로 분리됩니다. xmlns 선언은 페이지 설정에 따라 속성 형태의 프로퍼티로 보존되거나 삭제될 수 있습니다.
JSON에서 원래 XML로 정확히 복원할 수 있나요?
일반적으로 라운드트립은 무손실이 아니며, 특히 혼합 내용, 주석, 처리 명령, 속성 순서에서 차이가 납니다. 데이터 위주 XML(설정, 단순 레코드)이라면 보통 잘 복원되지만, 문서형 XML(DocBook, HTML, RSS)에는 실제 XML 파서를 사용하세요.
빈 요소 <foo/>와 <foo></foo>는 같은가요?
파서 입장에서는 동일합니다. 둘 다 빈 문자열이나 null 값을 가진 foo 프로퍼티로 변환됩니다. self-closing 표기는 XML에서 순전히 표기상의 차이일 뿐입니다.
변환은 로컬에서 이루어지나요?
네. XML 파싱과 JSON 생성은 브라우저에서 수행됩니다. 페이지가 데이터를 업로드하지 않습니다.