1. XML 소개
오늘날 JSON이 표준이지만, Java 세계에는 레거시 코드가 많아 때때로 XML을 접하게 됩니다. 따라서 XML에 대한 기본 이해는 유용합니다. XML (eXtensible Markup Language)는 구조화된 데이터를 저장하고 교환하기 위한 텍스트 형식입니다. 구성 파일, 프로그램 간 데이터 교환, 데이터 저장, 심지어 객체 직렬화에도 자주 사용됩니다.
XML 문서 구조의 기본 요소:
태그(요소):
<와 > 사이에 있는 모든 것입니다. 각 태그는 여는 태그(<tag>)와 닫는 태그(</tag>)로 이루어지거나, 자기 닫힘(<tag/>)일 수 있습니다.
속성:
태그 내부의 추가 매개변수입니다.
예: <user name="Vasya" age="25"/>
텍스트 노드:
태그 사이의 텍스트입니다.
예: <greeting>안녕, 세계!</greeting>
간단한 XML 문서 예시
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user name="Vasya" age="25">안녕!</user>
<user name="Katya" age="30"/>
</users>
여기서:
- <users> — 루트 요소입니다.
- <user> — name과 age 속성을 가진 요소이며, 첫 번째 사용자에는 텍스트 내용이 있습니다.
2. 핵심 개념
프롤로그:
파일 맨 앞의 행으로 XML 버전과 인코딩을 지정합니다.
예: <?xml version="1.0" encoding="UTF-8"?>
요소:
XML의 기본 구성 블록입니다.
예: <book>...</book>
속성:
여는 태그 내부의 매개변수입니다.
예: <book title="Java" author="Ivanov"/>
주석:
HTML과 마찬가지로 <!-- ... --> 사이에 작성합니다.
예: <!-- 이것은 주석입니다 -->
CDATA 섹션:
<, & 등의 문자가 있어도 XML로 해석되지 않도록 텍스트를 삽입할 수 있습니다.
예:
<script><![CDATA[
if (a < b && b > 0) { ... }
]]></script>
3. XML에서 네임스페이스가 필요한 이유
문제: 이름 충돌
큰 XML 문서에서는 이름이 같지만 의미가 다른 태그가 자주 등장합니다. 예를 들어 HTML의 <table>과 비즈니스 로직(예: 데이터베이스)의 <table>이 있을 수 있습니다. 어떤 태그가 무엇을 의미하는지 어떻게 구분할까요?
네임스페이스 없이:
<root>
<table>
<row>...</row>
</table>
<table>
<column>...</column>
</table>
</root>
여기서는 어떤 <table>이 무엇에 해당하는지 알 수 없습니다.
해결: 네임스페이스
네임스페이스는 요소와 속성에 “표식”을 달아 이름 충돌을 피하고 서로 다른 태그의 의미를 명확히 구분하는 방법입니다.
- 각 네임스페이스는 고유한 URI입니다(보통 링크처럼 보이지만 단지 식별자일 뿐입니다).
- 네임스페이스가 다르면 이름이 같아도 요소와 속성은 서로 다른 것으로 간주됩니다.
장점:
- 서로 다른 표준과 스키마 간 이름 충돌이 없습니다.
- 서로 다른 소스의 데이터를 한 문서에 결합할 수 있습니다.
- 각 태그가 어떤 “어휘(vocabulary)”에 속하는지 명확합니다.
4. 네임스페이스 사용: 선언과 적용
네임스페이스 선언 방법
요소의 여는 태그에 특수 속성 xmlns(XML Namespace)를 작성합니다:
- 접두사 없이: xmlns="URI" — 모든 하위 요소에 대한 기본 네임스페이스를 선언합니다.
- 접두사와 함께: xmlns:prefix="URI" — 태그에서 사용할 짧은 이름(접두사)을 가진 네임스페이스를 선언합니다.
네임스페이스 선언 및 사용 예
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="http://www.w3schools.com/furniture">
<h:table>
<h:tr>
<h:td>셀 1</h:td>
<h:td>셀 2</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>테이블</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>
여기서:
- xmlns:h="..." — HTML 테이블을 위한 h 접두사를 선언합니다.
- xmlns:f="..." — 가구(furniture)를 위한 f 접두사를 선언합니다.
- <h:table>과 <f:table>은 이름이 같아도 이제 서로 다른 요소입니다.
네임스페이스 사용 방법
- 선언: 루트 또는 임의의 요소에서 xmlns:prefix="URI" 형태로 선언합니다.
- 적용: 요소나 속성 이름 앞에 접두사와 콜론을 붙입니다: <prefix:element>...</prefix:element>
기본 네임스페이스
xmlns="URI"만 선언하면, 접두사가 없는 모든 요소가 해당 네임스페이스에 속합니다.
<books xmlns="http://example.com/books">
<book>...</book>
</books>
5. 실습: 여러 네임스페이스를 가진 간단한 XML 문서 만들기
HTML과 가구용 두 가지 네임스페이스를 사용하는 XML 문서 예제를 만들어 봅시다.
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="http://www.w3schools.com/furniture">
<h:table>
<h:tr>
<h:td>셀 1</h:td>
<h:td>셀 2</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>테이블</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>
여기서 일어나는 일:
- 루트 요소에서 두 개의 네임스페이스(h와 f)를 선언했습니다.
- h: 접두사가 붙은 모든 요소는 HTML 테이블에 해당합니다.
- f: 접두사가 붙은 모든 요소는 가구(furniture)에 해당합니다.
6. 흔한 오류
오류 1: 접두사 선언 누락
<root>
<h:table>...</h:table>
</root>
결과: XML 파서가 다음 오류를 표시합니다: The prefix 'h' for element 'h:table' is not bound.
오류 2: 네임스페이스 없이 동일한 이름
<root>
<table>...</table>
<table>...</table>
</root>
결과: 어떤 <table>이 무엇에 해당하는지 구분할 수 없습니다.
오류 3: 접두사 사용이 잘못됨
<root xmlns:h="http://www.w3.org/TR/html4/">
<h:table>...</h:table>
<f:table>...</f:table> <!-- 오류: 접두사 f가 선언되지 않았습니다 -->
</root>
결과: 파서 오류: The prefix 'f' for element 'f:table' is not bound.
GO TO FULL VERSION