이 문서의 과거 버전 (r1)을 보고 있습니다. 수정일: 2026.02.24 02:52
XML은 월드 와이드 웹 컨소시엄(W3C)이 표준화한 마크업 언어이다. 1998년에 처음 등장한 이 언어는 SGML의 복잡성을 줄이고 인터넷 환경에 적합하도록 설계된 메타 언어로, 데이터를 구조적으로 표현하기 위한 일련의 규칙 집합을 정의한다.
주요 용도는 데이터 저장 및 데이터 교환이다. 웹 서비스의 초기 프로토콜인 SOAP와 XML-RPC에서 데이터 포맷으로 사용되었으며, 마이크로소프트 오피스와 리브레오피스의 문서 형식인 Office Open XML과 OpenDocument의 기반이 된다. 또한 소프트웨어의 구성 파일을 작성하는 데 널리 활용된다.
XML은 HTML과 달리 태그를 사용자가 직접 정의할 수 있어 다양한 분야의 데이터를 기술하는 데 유연하게 적용된다. 이는 웹 기술, 데이터 직렬화, 문서 표준 등 관련 분야의 발전에 기여하며, 구조화된 정보 교환의 사실상 표준으로 자리 잡았다.
XML 문서의 시작 부분에 위치하는 프롤로그는 문서가 XML 문서임을 선언하고 문서를 처리하는 데 필요한 기본 정보를 제공하는 부분이다. 프롤로그는 선택 사항이지만, 포함될 경우 반드시 문서의 가장 첫 부분에 와야 한다. 일반적으로 XML 선언문으로 시작하며, 그 뒤에 선택적으로 문서 타입 선언이나 처리 명령이 올 수 있다.
프롤로그의 핵심 구성 요소는 XML 선언문이다. 이 선언은 <?xml로 시작하여 ?>로 끝나며, 문서가 XML 버전 1.0 또는 1.1을 따름을 명시한다. 선언문 내에는 인코딩 방식을 지정하는 속성과 문서의 독립성을 나타내는 속성을 포함할 수 있다. 인코딩 속성이 생략되면 기본값은 UTF-8 또는 UTF-16으로 간주된다.
프롤로그에 문서 타입 선언이 포함되면, 이는 문서의 구조를 정의하는 DTD(Document Type Definition)를 참조한다. DTD는 문서 내에서 사용할 수 있는 요소와 속성의 유형, 그들 간의 관계를 규정한다. 또한 프롤로그에는 주석이나 특정 애플리케이션을 위한 처리 명령이 포함될 수도 있다.
프롤로그의 존재 여부와 내용은 XML 파서가 문서를 올바르게 해석하는 데 중요한 역할을 한다. 특히 인코딩 정보는 파서가 문자를 정확하게 읽는 데 필수적이다. 따라서 국제화된 문서나 특정 문자 집합을 사용하는 데이터를 교환할 때는 프롤로그를 명시적으로 작성하는 것이 권장된다.
루트 요소는 XML 문서의 최상위 계층에 위치하는 단 하나의 요소를 가리킨다. 이 요소는 문서 전체 내용을 담는 컨테이너 역할을 하며, 문서 트리 구조의 시작점이 된다. 모든 다른 요소와 텍스트 내용은 이 루트 요소의 자식 또는 후손으로 중첩되어 구성된다. 따라서 루트 요소는 문서의 논리적 뼈대를 정의하는 기초가 된다.
루트 요소의 이름은 문서의 종류나 포함된 데이터의 성격을 반영하여 자유롭게 지을 수 있다. 예를 들어, 주소록 데이터를 표현하는 XML 문서라면 <addressbook>을, 주문 정보라면 <order>를 루트 요소로 사용할 수 있다. 루트 요소는 반드시 프롤로그 (선언문 등) 뒤에 와야 하며, 문서의 마지막에서 닫는 태그로 종료되어야 한다. 이는 잘 구성된 XML 문서의 필수 조건 중 하나이다.
하나의 XML 문서에는 오직 하나의 루트 요소만 존재해야 한다. 여러 개의 최상위 요소가 병렬로 존재하는 것은 XML 문법상 허용되지 않는다. 이러한 단일 루트 요소 규칙은 문서 파싱 시 명확한 계층 구조를 보장하며, DOM 파서가 문서 객체 모델 트리를 생성할 때 출발점을 제공한다. 루트 요소는 속성을 가질 수 있어 문서 전체에 적용되는 메타데이터를 포함할 수도 있다.
루트 요소의 개념은 XML이 메타 언어로서 다양한 문서 표준을 정의하는 데 핵심적이다. 예를 들어, 웹 서비스 프로토콜인 SOAP은 특정 루트 요소를 규정하며, Office Open XML이나 OpenDocument 같은 문서 형식도 각자 고유의 루트 요소 구조를 정의한다. 이는 서로 다른 시스템 간 데이터 교환이 표준화된 방식으로 이루어질 수 있도록 한다.
XML 문서의 핵심 구성 단위는 요소(Element)이다. 요소는 시작 태그와 종료 태그로 둘러싸여 문서의 계층적 구조를 형성한다. 시작 태그는 <요소이름> 형태이며, 종료 태그는 </요소이름> 형태로 작성한다. 이 두 태그 사이에 위치하는 내용이 해당 요소의 값이 된다.
요소는 다른 요소를 포함하거나 텍스트 데이터를 담을 수 있으며, 이를 통해 복잡한 데이터 구조를 표현한다. 예를 들어, <책>이라는 요소 안에 <제목>과 <저자>라는 하위 요소를 포함시킬 수 있다. 요소는 반드시 적절하게 중첩되어야 하며, 시작 태그와 종료 태그의 쌍이 명확하게 맞아야 한다.
요소의 내용은 텍스트, 다른 요소, 또는 이 둘의 혼합일 수 있다. 내용이 전혀 없는 요소는 빈 요소라고 하며, <요소이름 />과 같은 축약형 태그로 표현할 수 있다. 모든 XML 문서는 정확히 하나의 루트 요소를 가져야 하며, 나머지 모든 요소는 이 루트 요소의 자식 또는 후손 요소로 존재한다.
속성은 XML 요소에 추가적인 정보를 부여하는 이름-값 쌍이다. 속성은 요소의 시작 태그 내에 이름="값" 형태로 작성되며, 주로 해당 요소에 대한 메타데이터나 요소의 동작 방식을 제어하는 데 사용된다. 예를 들어, <img src="image.jpg" width="300">에서 src와 width는 이미지 요소의 속성이다. 속성 값은 반드시 작은따옴표나 큰따옴표로 둘러싸여야 하며, 동일한 요소 내에서 같은 속성 이름을 두 번 사용할 수 없다.
속성은 요소의 내용이 아닌 요소 자체에 대한 정보를 기술할 때 적합하다. 예를 들어, 문서의 고유 식별자(id), 스타일 지정(class), 참조 링크(href) 등을 표현하는 데 주로 활용된다. 그러나 복잡한 데이터나 계층 구조를 가진 정보는 속성보다는 중첩된 자식 요소를 사용하여 표현하는 것이 일반적인 관행이다. 이는 데이터의 확장성과 가독성을 높이는 데 도움이 된다.
XML에서 속성의 사용은 문서 타입 정의(DTD)나 XML 스키마(XSD)와 같은 스키마 언어를 통해 정의 및 제한될 수 있다. 스키마에서는 특정 요소에 허용되는 속성의 이름, 데이터 타입, 필수 여부, 기본값 등을 명시함으로써 유효한 XML 문서의 조건을 규정한다. 속성은 잘 구성된 XML 문서를 작성하는 기본 규칙을 준수해야 하며, XML 파싱 과정에서 요소와 함께 처리되어 애플리케이션에 전달된다.
XML 문서의 시작 부분에 위치하는 선언문은 해당 문서가 XML 문서임을 명시하고, 문서의 버전과 인코딩 방식을 정의하는 역할을 한다. 이 선언은 XML 파서가 문서를 올바르게 해석하는 데 필수적인 정보를 제공한다.
선언문은 <?xml로 시작하여 ?>로 끝나며, 일반적으로 문서의 첫 번째 줄에 위치한다. 가장 기본적인 구성은 버전 정보를 나타내는 version 속성이다. XML 1.0과 XML 1.1이 존재하지만, 현재 대부분의 시스템은 XML 1.0을 표준으로 사용한다. 예를 들어, <?xml version="1.0"?>과 같은 형태가 가장 간단한 선언문이다.
선언문에는 선택적으로 encoding 속성을 추가하여 문서의 문자 인코딩 방식을 명시할 수 있다. 이는 문서 내에 특수 문자가 포함된 경우 올바른 표시를 보장하는 데 중요하다. 일반적으로 사용되는 인코딩 값으로는 UTF-8, ISO-8859-1 등이 있다. 예를 들어, <?xml version="1.0" encoding="UTF-8"?>과 같이 작성한다.
또한, standalone 속성을 사용하여 문서가 외부 문서 타입 정의나 다른 파일에 의존하는지 여부를 선언할 수 있다. 이 속성의 값은 "yes" 또는 "no"이며, 기본값은 "no"이다. 이는 문서가 단독으로 처리될 수 있는지를 나타내는 지시자 역할을 한다. 선언문은 XML 문서가 잘 구성된 XML이 되기 위한 첫 번째 조건을 구성한다.
XML에서 요소는 문서의 기본적인 구성 단위이다. 요소는 시작 태그와 종료 태그로 둘러싸여 있으며, 그 사이에 내용을 포함한다. 시작 태그는 <요소이름>의 형태이고, 종료 태그는 </요소이름>의 형태로 작성된다. 예를 들어, <message>Hello</message>에서 message가 요소 이름이며, Hello가 그 내용이다.
요소는 다른 요소를 포함할 수 있어 계층적인 구조를 형성한다. 이렇게 중첩된 구조는 데이터 간의 관계를 명확히 표현한다. 예를 들어, <book> 요소 안에 <title>과 <author> 요소를 포함시켜 책 정보를 구성할 수 있다. 모든 XML 문서는 반드시 하나의 루트 요소를 가져야 하며, 다른 모든 요소는 이 루트 요소의 자식 또는 후손 요소로 존재한다.
요소의 이름은 대소문자를 구분하며, 시작 태그와 종료 태그의 이름은 정확히 일치해야 한다. 이름은 문자, 숫자, 하이픈, 밑줄, 마침표 등을 사용할 수 있으나, 공백은 포함할 수 없다. 또한 이름은 숫자나 구두점으로 시작할 수 없다. 올바른 요소 이름의 예로는 item, book-title, _price 등이 있다.
요소는 속성을 가질 수 있으며, 속성은 시작 태그 내에 이름="값" 형태로 작성되어 요소에 대한 추가 정보를 제공한다. 요소의 내용은 텍스트, 다른 요소, 또는 이 둘의 혼합이 될 수 있다. 내용이 없는 요소는 빈 요소라고 하며, <br/>과 같이 시작 태그와 종료 태그를 합쳐서 표현할 수 있다.
속성은 XML 요소에 대한 추가 정보를 제공하는 이름-값 쌍이다. 속성은 요소의 시작 태그 내에 위치하며, 요소 자체의 내용이 아닌 해당 요소의 특성이나 메타데이터를 정의하는 데 사용된다. 예를 들어, <book id="123">에서 id는 속성 이름이고 "123"은 속성 값이다. 속성 값은 항상 따옴표(작은따옴표 또는 큰따옴표)로 묶어야 하며, 하나의 요소는 여러 개의 속성을 가질 수 있다.
속성은 주로 요소를 식별하거나(id, name), 요소의 상태를 나타내거나(disabled, checked), 요소에 대한 추가 데이터를 첨부하는(author, date) 목적으로 활용된다. 그러나 동일한 정보를 요소의 자식 요소로 중첩하여 표현할 수도 있기 때문에, 데이터를 속성으로 표현할지 자식 요소로 표현할지에 대한 설계 결정이 필요하다. 일반적으로 메타데이터는 속성으로, 실제 문서 내용이나 복잡한 데이터는 자식 요소로 표현하는 것이 관례이다.
사용 예시 | 설명 |
|---|---|
|
|
|
|
|
|
속성의 사용은 문서 타입 정의(DTD)나 XML 스키마(XSD)와 같은 스키마 언어를 통해 제약 조건을 정의할 수 있다. 이를 통해 특정 요소가 가질 수 있는 속성의 이름, 데이터 타입, 기본값, 필수 여부 등을 규정함으로써 유효한 XML 문서를 보장하는 데 기여한다.
XML 문서에서 요소의 시작 태그와 종료 태그 사이에 위치하는 실제 데이터를 텍스트 내용이라고 한다. 이는 문서가 담고자 하는 핵심 정보를 구성하며, 문자열 형태로 표현된다. 텍스트 내용은 공백 문자나 줄바꿈을 포함할 수 있으며, XML 파서는 이를 그대로 유지하여 처리한다.
텍스트 내용 내에는 마크업으로 해석될 수 있는 특수 문자(예: <, >, &)가 포함될 수 있다. 이를 그대로 사용하면 파싱 오류가 발생할 수 있으므로, XML에서는 미리 정의된 엔티티 참조를 사용하여 이스케이프 처리해야 한다. 예를 들어 <는 <로, &는 &로 변환하여 작성한다. 대량의 특수 문자가 포함된 텍스트를 안전하게 포함시키기 위해 CDATA 섹션을 사용할 수도 있다.
텍스트 내용은 단순한 문자열 데이터뿐만 아니라, 다른 요소를 중첩하여 포함하는 혼합 콘텐츠 모델의 일부가 될 수도 있다. 이 경우 텍스트와 자식 요소가 함께 존재하게 되며, 문서의 문서 타입 정의나 XML 스키마에 정의된 콘텐츠 모델을 따라야 한다. 텍스트 내용의 처리는 DOM 파서나 SAX 파서와 같은 XML 파싱 도구의 핵심 기능 중 하나이다.
XML 문서에서 주석은 문서의 내용이나 구조에 대한 설명을 추가하기 위해 사용된다. 주석은 XML 파서가 처리하지 않으며, 문서의 논리적 구조나 데이터 표현에 영향을 주지 않는 부가 정보를 담는다. 주석은 주로 개발자나 문서 작성자가 코드를 이해하는 데 도움을 주거나, 특정 부분을 임시로 비활성화하는 용도로 활용된다.
주석은 특별한 문법으로 작성된다. 주석의 시작은 <!--로 표시하고, 끝은 -->로 표시한다. 이 두 마커 사이에 작성된 모든 텍스트는 주석으로 간주된다. 주석은 요소 내부나 외부, 루트 요소 전후 등 문서의 대부분의 위치에 배치할 수 있으나, 선언문 내부나 태그 이름 안에는 삽입할 수 없다. 또한 주석 안에 또 다른 주석을 중첩해서 사용하는 것(<!-- <!-- 내용 --> -->)은 허용되지 않는다.
주석의 일반적인 사용 예는 코드에 대한 설명, 수정 이력 기록, 특정 요소나 속성의 용도 설명, 또는 디버깅을 위해 일시적으로 일부 마크업을 실행에서 제외시키는 것이다. 그러나 주석은 공식적인 메타데이터를 기록하는 용도로는 적합하지 않으며, 문서의 버전 관리나 중요한 설정 정보는 주석 대신 적절한 요소나 속성을 통해 표현하는 것이 바람직하다.
XML을 처리하는 DOM 파서나 SAX 파서와 같은 XML 파싱 도구들은 일반적으로 주석 내용을 무시하거나, 별도의 인터페이스를 통해 접근할 수 있도록 한다. 이는 주석이 애플리케이션의 핵심 데이터 교환 로직과는 분리되어야 함을 의미한다. 따라서 잘 구성된 XML 문서를 작성할 때는 주석의 사용이 문서의 문법적 정합성을 해치지 않도록 주의해야 한다.
처리 명령은 XML 문서 내에서 애플리케이션에 특정 명령을 전달하기 위해 사용되는 지시문이다. 이는 문서의 데이터나 구조 자체를 표현하는 것이 아니라, 해당 XML 문서를 처리하는 소프트웨어(예: 파서 또는 특정 애플리케이션)에게 정보를 제공하는 역할을 한다. 처리 명령은 <?로 시작하고 ?>로 끝나는 구문으로 작성되며, 첫 번째 단어는 처리 명령의 대상을 지정하는 대상(PITarget)으로, 그 뒤에 애플리케이션에 전달할 데이터인 명령(PIData)이 옵니다.
가장 대표적인 예는 XML 선언(<?xml version="1.0"?>)이지만, 이는 특별한 경우로 보통 처리 명령과는 별도로 취급한다. 일반적인 처리 명령의 예로는 XSLT 변환을 지시하는 <?xml-stylesheet type="text/xsl" href="style.xsl"?>이 있다. 이 처리 명령은 XML 문서를 처리하는 브라우저나 다른 도구에게 해당 문서를 어떻게 표시하거나 변환할지에 대한 힌트를 준다. 또한 PHP와 같은 서버 사이드 스크립트를 포함시키기 위해 <?php ... ?>와 같은 형태로 사용되기도 한다.
처리 명령의 내용과 해석은 전적으로 이를 처리하는 애플리케이션에 달려 있으며, XML 표준은 그 구문만을 정의한다. 따라서 모든 XML 파서가 처리 명령을 인식하고 애플리케이션에 전달할 수는 있지만, 그 명령을 이해하고 실행하는 것은 해당 애플리케이션의 몫이다. 잘 구성된 XML 문서를 작성할 때는 특정 애플리케이션에 종속적인 처리 명령의 사용을 최소화하고, 대체 수단(예: 네임스페이스를 이용한 확장 요소)을 고려하는 것이 문서의 호환성을 높이는 방법이 될 수 있다.
CDATA 섹션은 XML 문서 내에서 특수 문자를 일반 텍스트로 처리하도록 지정하는 영역이다. 이 섹션 안에 포함된 텍스트는 XML 파서에 의해 마크업이나 엔티티 참조로 해석되지 않으며, 문자 그대로의 데이터로 간주된다. 주로 HTML 코드, 자바스크립트나 CSS 스크립트, 또는 XML이나 SQL 쿼리와 같이 '<', '>', '&'와 같은 특수 문자가 많이 포함된 데이터를 XML 요소의 내용으로 안전하게 포함시키기 위해 사용된다.
CDATA 섹션은 <![CDATA[로 시작하여 ]]>로 끝난다. 이 두 구분자 사이의 모든 내용은 파서가 무시하는 원시 텍스트로 처리된다. 예를 들어, <script><![CDATA[ if (a < b && b > c) { ... } ]]></script>와 같이 작성하면, 비교 연산자 '<', '>' 그리고 '&&'가 XML의 마크업이나 엔티티 시작으로 오인되지 않는다.
이 기능은 잘 구성된 XML 문서를 작성하는 데 유용하지만, 남용은 피해야 한다. CDATA 섹션 내부에는 그 종료 문자열인 ]]>를 포함할 수 없으며, 중첩 사용도 불가능하다. 또한, XML 스키마를 사용한 유효성 검사 시 CDATA 섹션의 내용은 여전히 해당 요소가 정의한 데이터 타입의 제약을 받는다. 데이터 교환의 명확성과 호환성을 위해, 가능하면 특수 문자를 해당 엔티티 참조(예: <, >, &)로 대체하는 것이 더 권장되는 방법이다.
문서 타입 정의는 XML 문서의 구조와 내용을 정의하는 공식적인 규칙 집합이다. 이는 해당 XML 문서가 어떤 요소와 속성을 가질 수 있는지, 그들이 어떤 순서로 나타나야 하는지, 그리고 어떤 내용을 포함할 수 있는지를 명시한다. DTD는 주로 SGML과 초기 XML 애플리케이션에서 문서의 유효성을 검증하는 데 사용되었다.
DTD는 크게 내부 DTD와 외부 DTD로 구분된다. 내부 DTD는 XML 문서 자체 내에 선언문과 함께 정의되는 반면, 외부 DTD는 별도의 파일(.dtd)로 작성되어 여러 XML 문서에서 참조하여 재사용할 수 있다. 외부 DTD는 특히 특정 산업이나 분야에서 표준화된 데이터 교환 형식을 정의할 때 널리 활용되었다.
DTD의 구문은 요소 선언, 속성 목록 선언, 엔티티 선언 등으로 구성된다. 예를 들어, 요소 선언을 통해 해당 요소가 포함해야 할 자식 요소의 순서와 반복 횟수를 규정할 수 있다. 그러나 DTD는 데이터 타입을 문자열로만 제한하는 등 제약이 많고, XML 구문 자체를 사용하지 않아 확장성이 부족한 단점이 있다.
이러한 한계로 인해 보다 강력하고 유연한 스키마 언어인 XML 스키마(XSD)가 등장하게 되었다. 현대의 웹 서비스나 복잡한 데이터 직렬화에는 XSD가 더 널리 사용되지만, DTD는 여전히 일부 레거시 시스템이나 간단한 문서 형식 정의에서 그 역할을 하고 있다.
XSD는 XML 스키마 정의 언어의 약자로, 월드 와이드 웹 컨소시엄(W3C)이 권고한 XML 문서의 구조와 내용을 정의하고 제약하는 공식적인 스키마 언어이다. 1998년에 처음 등장한 XSD는 DTD(문서 타입 정의)의 한계를 극복하고자 개발되었으며, 데이터 타입을 명시적으로 정의하고 네임스페이스를 완벽하게 지원하는 등 더욱 강력하고 유연한 스키마 기능을 제공한다.
XSD 문서 자체도 XML 문법을 따르기 때문에, 일반적인 XML 편집기나 파서로 처리할 수 있다는 장점이 있다. XSD는 요소와 속성의 계층 구조, 발생 횟수, 데이터 형식(문자열, 숫자, 날짜 등), 기본값 등을 상세히 규정한다. 이를 통해 생성된 XML 스키마는 해당 형식을 따르는 XML 문서가 유효한지 검증하는 기준이 된다.
XSD는 웹 서비스의 데이터 교환 형식을 정의하는 데 널리 사용되며, 마이크로소프트 오피스의 파일 형식인 오피스 오픈 XML과 같은 복잡한 문서 표준의 기반이 되기도 한다. 또한 자바, C# 등의 프로그래밍 언어에서는 XSD를 기반으로 클래스 코드를 자동 생성하는 도구를 제공하여, 데이터 바인딩과 직렬화 과정을 단순화한다.
XML 문서에서 네임스페이스는 요소와 속성의 이름이 충돌하는 것을 방지하기 위한 체계이다. 서로 다른 XML 어휘나 스키마에서 동일한 이름을 가진 요소가 혼용될 때, 각각을 고유하게 식별할 수 있도록 접두사와 URI를 결합하여 사용한다. 이는 특히 여러 XML 어휘를 조합하여 사용하는 웹 서비스나 복잡한 문서 형식에서 필수적이다.
네임스페이스는 일반적으로 xmlns 속성을 사용하여 선언한다. 기본 네임스페이스는 xmlns="URI" 형태로 선언하며 접두사 없이 사용할 수 있다. 특정 접두사를 가진 네임스페이스는 xmlns:접두사="URI" 형태로 선언한 후, 요소나 속성 이름 앞에 접두사:를 붙여 사용한다. 여기서 URI는 실제로 리소스를 가리키기보다는 고유한 식별자 역할을 한다.
네임스페이스의 적용 범위는 선언이 이루어진 요소와 그 하위 요소 모두에 영향을 미친다. 이를 통해 문서 내에서 논리적으로 구분된 여러 영역에 서로 다른 네임스페이스를 적용할 수 있다. 네임스페이스의 적절한 사용은 잘 구성된 XML 문서 작성과 유효한 XML 검증 과정에서 중요한 요소가 된다.
잘 구성된 XML은 XML 문서가 준수해야 하는 기본적인 문법 규칙을 충족하는 상태를 가리킨다. 이는 XML 파서가 문서를 성공적으로 해석하고 처리할 수 있도록 하는 최소한의 조건이다. 문서가 잘 구성되었다는 것은 특정 문서 타입 정의나 XML 스키마에 대한 유효성 검사를 통과했다는 의미는 아니며, 순수하게 문법적 정확성을 의미한다.
잘 구성된 XML 문서의 핵심 규칙은 다음과 같다. 문서는 정확히 하나의 루트 요소를 가져야 하며, 모든 요소는 시작 태그와 종료 태그로 올바르게 닫혀 있어야 한다. 요소들은 서로 올바르게 중첩되어야 하며, 태그의 대소문자도 일관되게 사용되어야 한다. 또한 속성 값은 반드시 따옴표(작은따옴표 또는 큰따옴표)로 둘러싸여야 한다.
이러한 규칙을 지키지 않을 경우, 예를 들어 태그가 닫히지 않거나 요소 중첩 순서가 잘못되면, XML 파서는 문서를 처리하는 과정에서 오류를 발생시키고 파싱을 중단한다. 따라서 잘 구성됨은 XML 문서가 기능하기 위한 필수 전제 조건이다. 웹 브라우저나 다양한 애플리케이션에서 XML 데이터를 교환하거나 구성 파일로 사용할 때, 이 기본 문법이 지켜지지 않으면 데이터 읽기 자체가 불가능해진다.
잘 구성된 XML과 유효한 XML의 개념은 구분된다. 잘 구성됨은 문법의 정확성을, 유효함은 문서의 구조와 내용이 미리 정의된 DTD나 스키마의 규칙을 따르는지를 의미한다. 모든 유효한 XML 문서는 잘 구성되어 있어야 하지만, 잘 구성된 문서가 반드시 특정 스키마에 유효할 필요는 없다.
유효한 XML 문서는 특정 구조적 규칙과 문법적 규칙을 모두 준수하는 문서를 말한다. 이는 문서가 단순히 XML의 기본 구문 규칙(예: 태그의 올바른 중첩, 닫는 태그의 존재 등)을 따르는 '잘 구성된 XML' 상태를 넘어, 사전에 정의된 구조적 제약 조건을 만족해야 함을 의미한다. 이러한 제약 조건은 주로 문서 타입 정의(DTD)나 XML 스키마(XSD)와 같은 스키마 언어로 정의된다.
유효성 검사는 XML 문서가 해당 스키마에 명시된 요소의 순서, 데이터 타입, 허용된 속성 값 등을 정확히 준수하는지 확인하는 과정이다. 예를 들어, 스키마에서 '주문' 요소 내에 반드시 하나의 '고객ID' 요소가 포함되어야 한다고 정의했다면, 유효한 XML 문서는 이를 반드시 지켜야 한다. 이 검사는 주로 XML 파서에 내장된 검증기 또는 별도의 검증 도구를 통해 수행된다.
유효성은 데이터 교환의 신뢰성을 보장하는 데 핵심적이다. 웹 서비스 간 SOAP 메시지를 주고받거나, 오피스 문서 형식(Office Open XML, OpenDocument)으로 파일을 저장할 때, 사전에 합의된 스키마에 따라 문서가 생성되고 검증됨으로써 상호 운용성이 확보된다. 또한 구성 파일이나 데이터 직렬화 형식으로 사용될 때도 일관된 데이터 구조를 유지할 수 있게 한다.
구분 | 잘 구성된 XML | 유효한 XML |
|---|---|---|
필수 조건 | XML 기본 문법 규칙 준수 | 잘 구성된 상태 + 스키마 규칙 준수 |
검증 기준 | XML 파서의 구문 분석 | DTD 또는 XML 스키마 |
주요 목적 | 문서의 파싱 가능성 보장 | 데이터 구조와 내용의 정확성 보장 |
따라서 유효한 XML은 단순히 기계가 읽을 수 있는 형태를 넘어, 특정 도메인이나 애플리케이션 간에 의미 있고 정확한 데이터 교환이 가능하도록 하는 표준화된 계약의 역할을 한다.
DOM 파서는 XML 문서를 처리하는 방식 중 하나로, 문서 전체를 한 번에 메모리로 읽어들여 트리 구조의 객체 모델을 생성한다. 이렇게 생성된 모델을 문서 객체 모델(DOM)이라고 부른다. DOM은 문서의 요소, 속성, 텍스트 등 모든 구성 요소를 노드로 표현하며, 이 노드들이 부모-자식 관계로 연결되어 전체 문서의 계층 구조를 형성한다. 애플리케이션은 이 메모리 상의 트리 구조를 통해 문서의 특정 부분을 탐색하거나, 내용을 수정하거나, 새로운 구조를 추가하는 등 프로그래밍 방식으로 자유롭게 조작할 수 있다.
DOM 파서의 주요 특징은 문서 전체를 메모리에 로드한다는 점이다. 이 방식은 문서 구조에 대한 임의 접근이 가능하고, 문서를 편집하거나 복잡한 질의를 수행하는 데 유리하다. 예를 들어, 자바스크립트가 웹 브라우저에서 HTML 문서를 조작할 때 사용하는 것이 바로 DOM 인터페이스이다. 그러나 문서의 크기가 매우 클 경우, 모든 내용을 메모리에 유지해야 하므로 성능과 메모리 사용량 측면에서 부담이 될 수 있다는 단점이 있다.
DOM 파서의 대안으로는 SAX 파서가 있다. SAX 파서는 문서를 처음부터 끝까지 순차적으로 읽어가며 이벤트를 발생시키는 방식으로, 문서 전체를 메모리에 올리지 않기 때문에 대용량 문서 처리에 효율적이다. 따라서 DOM은 문서의 작은 부분을 빈번히 수정하거나 탐색해야 하는 상호작용적인 애플리케이션에 적합하고, SAX는 문서를 한 번만 읽고 필요한 데이터를 추출하는 스트리밍 처리에 적합하다고 볼 수 있다.
DOM 파서를 사용하기 위해서는 프로그래밍 언어별로 제공되는 XML 처리 라이브러리를 활용한다. 대표적인 예로 자바의 JAXP, 파이썬의 xml.dom 모듈, C++의 libxml2 등이 있다. 이러한 라이브러리들은 표준 W3C DOM 명세를 기반으로 구현되어, 개발자가 일관된 방식으로 XML 문서를 프로그램 내에서 객체처럼 다룰 수 있게 해준다.
SAX 파서는 XML 문서를 처리하는 방식 중 하나로, 문서를 읽어들이는 동안 발생하는 이벤트를 기반으로 동작한다. DOM 파서가 문서 전체를 메모리에 트리 구조로 로드하는 것과 달리, SAX 파서는 문서를 순차적으로 스캔하며 시작 태그, 종료 태그, 텍스트 데이터 등을 만날 때마다 응용 프로그램에 이벤트를 통지한다. 이 방식은 문서를 한 번만 훑고 지나가기 때문에 스트리밍 처리에 적합하며, 대용량 XML 문서를 다룰 때 메모리 사용 효율이 매우 높다는 장점이 있다.
SAX 파서의 핵심은 이벤트 기반의 콜백 메커니즘이다. 응용 프로그램은 원하는 이벤트(예: 요소 시작, 텍스트 발견)를 처리할 핸들러 메서드를 구현하고, 파서에 등록한다. 파서가 문서를 읽어가다가 해당 이벤트가 발생하면 등록된 핸들러 메서드를 자동으로 호출한다. 이는 문서 구조를 미리 알 필요 없이 필요한 데이터만 추출하는 필터링이나 간단한 검색에 유용하다. 그러나 문서의 임의 위치에 접근하거나 문서 구조를 수정하는 작업에는 적합하지 않다.
SAX 파싱의 주요 인터페이스로는 요소의 시작과 끝을 알리는 startElement, endElement 이벤트와 문자 데이터를 처리하는 characters 이벤트가 있다. 또한 네임스페이스 선언이나 처리 명령과 같은 다른 구문 요소에 대한 이벤트도 제공한다. SAX는 공식적인 W3C 권고안은 아니지만, 사실상의 표준으로 널리 채택되어 자바, 파이썬, C++ 등 다양한 프로그래밍 언어에서 라이브러리 형태로 지원된다.
SAX 파서의 단점은 애플리케이션이 이벤트 발생 순서와 상태를 직접 관리해야 하므로 로직이 복잡해질 수 있다는 점이다. 또한 문서 전체에 대한 랜덤 액세스가 불가능하여 DOM 파서에 비해 사용 사례가 제한적이다. 따라서 대용량 로그 파일의 실시간 처리, 서버에서 들어오는 XML 스트림의 즉시 분석, 또는 메모리 제약이 심한 임베디드 시스템 환경에서 SAX 파싱이 선호되는 편이다.