XML 구조
XML 트리
XML 문서는 HTML 문서와 마찬가지로 트리(tree) 형태의 계층 구조를 가진다.
이러한 XML 트리는 하나뿐인 루트(root) 요소부터 시작하여, 각각의 자식(child) 요소에 차례대로 연결된다.
XML 트리 구조에 포함되는 모든 요소는 자신만의 자식(child) 요소를 가질 수 있다.
위의 그림에서 화살표로 설명하는 용어들은 요소 간의 관계를 나타낸다.
부모(parent) 요소는 여러 개의 자식(child) 요소를 가질수 있다.
하지만 자식(child) 요소는 단 하나의 부모(parent) 요소만을 가진다.
형제(sibling) 요소는 같은 트리 레벨(tree level)에 존재하는 요소를 가리킨다.
즉, 형제 요소란 같은 부모(parent) 요소를 가지는 자식 요소 간의 관계를 나타낸다.
조상(ancestor) 요소란 부모 요소를 포함해 계층적으로 현재 요소보다 상위에 존재하는 모든 요소를 가리킨다.
자손(descendant) 요소란 자식 요소를 포함해 계층적으로 현재 요소보다 하위에 존재하는 모든 요소를 가리킨다.
XML 트리의 모든 요소는 자신만의 텍스트나 속성을 가질 수 있다.
XML 문서 구조
예제
<?xml version="1.0" encoding="UTF-8"?>
<shop city="서울" type="마트">
<food>
<name>귤</name>
<sort>과일</sort>
<cost>3000</cost>
</food>
<food>
<name>상추</name>
<sort>야채</sort>
<cost>2000</cost>
</food>
</shop>
XML 문서는 맨 첫줄에 <xml>태그를 사용하여 XML 문서임을 명시해야 한다.
예제
<?xml version="1.0" encoding="UTF-8"?>
그 다음에는 XML 문서에 단 하나만이 존재하는 루트(root) 요소를 생성한다.
이 루트 요소는 XML 문서에 존재하는 모든 요소의 조상(ancestor) 요소가 된다.
예제
<shop city="서울" type="마트">
위의 예제에서 루트 요소는 자식(child) 요소로 두 개의 <food>요소를 가진다.
예제
<shop city="서울" type="마트">
<food>
...
</food>
<food>
...
</food>
</shop>
첫 번째 <food>요소는 <name>요소, <sort>요소, <cost>요소의 총 세 개의 자식 요소를 가진다.
예제
<food>
<name>귤</name>
<sort>과일</sort>
<cost>3000</cost>
</food>
위와 같이 또 하나의 <food> 요소를 생성하고 XML 문서가 끝난다.
예제
<food>
<name>상추</name>
<sort>야채</sort>
<cost>2000</cost>
</food>
위에서 살펴본 XML 문서는 상점에서 판매하는 식품에 관한 정보를 담고 있는 문서임을 명확하게 알 수 있다.
이처럼 XML 문서에서 요소의 이름은 저장하고 있는 데이터의 내용을 명확히 알려준다.
따라서 요소의 이름만으로도 데이터의 내용을 짐작할 수 있다.
XML 선언
XML 문서는 맨 첫 줄에 <xml>태그를 사용하여 XML 문서임을 명시해야 한다.
이것을 XML 프롤로그(prolog)라고 하며, 이때 사용되는 <xml>태그의 이름은 소문자 xml로만 사용해야 한다.
XML 프롤로그의 문법은 다음과 같다.
문법
<?xml version="XML문서버전" encoding="문자셋" standalone="yes|no"?>
version 속성에는 XML 문서에 사용된 XML의 버전을 명시한다.
encoding 속성에는 XML 문서의 문자셋(character set)을 명시하며, 기본값은 UTF-8로 설정된다.
standalone 속성은 XML 문서가 외부 DTD(Document Type Definition)와 같은 외부 소스의 데이터에 의존하고 있는 문서인지 아닌지를 XML파서(parser)에 알려주는 역할을 한다.
이 속성의 기본값은 no이며, yes로 설정하면 이 문서를 파싱(parsing)할 때 참조해야 할 외부 소스가 없다는 것을 의미한다.
XML 문법
따라서 XML 문법은 배우기도 쉬우며, 사용하기도 쉽다.
1. 모든 XML 요소는 종료 태그를 가져야 한다.
HTML 에서는 종료 태그를 생략하거나, 빈 태그를 사용해도 대부분의 경우 문제없이 동작한다.
하지만 XML 에서는 XHTML과 마찬가지로 종료 태그가 생략되면 오류가 발생한다.
또한, 빈 태그에도 반드시 슬래시(/)를 추가해야만 오류가 발생하지 않는다.
예제
HTML : <h1>XML
<hr>
XML : <h1>XML</h1>
<hr />
2. XML 태그는 대소문자를 구분한다.
HTML 에서는 태그 이름에 대소문자를 구분하지 않는다.
하지만 XML 에서는 태그 이름에 대소문자를 구분하므로, 대소문자가 다르면 다른 요소로 인식한다.
예제
<lecture>이 요소는 lecture 요소입니다.</lecture>
<Lecture>이 요소는 Lecture 요소입니다.</Lecture>
3. XML에서는 시작 태그와 종료 태그가 모두 대소문자까지 같아야 한다.
XML에서는 태그 이름에 대소문자를 구분하므로, 시작 태그와 종료 태그의 대소문자가 모두 같아야 한다.
예제
<lecture>이 요소는 lecture 요소입니다.</lecture>
<Lecture>이 구문은 오류를 발생합니다.</lecture>
4. XML 태그의 여닫는 순서는 반드시 지켜져야 한다.
여닫는 순서가 지켜진다는 것은 먼저 열린 태그는 그 안의 모든 태그가 닫힌 후에야 닫힐 수 있다는 뜻이다.
예제
<p><strong>이 구문은 오류를 발생합니다.</p></strong>
<p><strong>이 구문이 정확한 순서입니다.</strong></p>
HTML에서는 속성값을 따옴표로 감싸지 않아도 큰 문제 없이 동작한다.
하지만 XML에서는 속성값을 따옴표로 감싸지 않으면 오류가 발생한다.
예제
<student name=홍길동> // 오류가 발생함.
<student name="이순신"> // 정상적으로 동작함.
6. XML에서는 띄어쓰기를 인식한다.
HTML에서는 띄어쓰기를 따로 인식하지 않는다.
하지만 XML에서는 여러 번의 띄어쓰기를 그대로 인식한다.
예제
코드 : <p>띄 어 쓰 기 </p>
HTML : 띄어쓰기
XML : 띄 어 쓰 기
XML 엔티티(Entity)
XML 에서는 예약되어 있는 다섯 개의 특별한 기호가 있다.
이렇게 예약되어 있는 기호를 XML 문서에서 사용하면 XML 파서(해석하는 기계)는 그것을 전혀 다른 의미로 해석한다.
따라서 이렇게 예약된 기호를 기존에 사용하던 의미 그대로 사용하기 위해서 만든 문자셋을 엔티티(entity) 라고 한다.
HTML에서는 수많은 문자와 기호를 엔티티로 미리 정의해 놓고 사용하고 있다.
하지만 XML에서 제공하는 엔티티는 다섯 개뿐이다.
다음 표는 XML에서 예약되어 있는 기호와 그에 따른 엔티티를 보여준다.
기호 |
엔티티 이름 | 16진수 엔티티 | 설명 |
< |
< | < | 보다 작은 |
< | > | > | 보다 큰 |
& | & | & | and 기호 |
" | " | " | 큰 따옴표 |
' | ' | ' | 작은따옴표 |
XML 주석(comment)
주석(comment)이란 개발자가 작성한 해당 코드에 대한 이해를 돕는 설명이나 디버깅을 위해 작성한 구문을 의미한다.
이러한 주석은 XML코드의 어느 부분에라도 작성할 수 있으며, 이러한 주석문은 XML 파서가 처리하지 않는다.
XML의 주석은 HTML의 주석과 같은 모양이다.
문법
<!-- 주석 내용 -->
XML의 주석은 <!--로 시작하여 -->로 끝난다.
주석의 시작 태그(<!--)에는 느낌표(!) 가 있지만 종료 태그(-->)에는 느낌표가 없다.
XML 주석에서 시작과 마지막의 하이픈(-)의 개수는 중요하지 않다.
다만, 주석의 내용 안에 두 개 이상의 연속된 하이픈은 허용하지 않는다.
다음 예제는 주석의 내용 안에 두 개의 연속된 하이픈이 존재하기 때문에 요류가 발생한다.
예제
<!----- 이것은 주석 -- 이 아닙니다. --> // 오류가 발생함.
예제
<!----- 이것은 주석 - - 입니다. --> // 주석으로 정상 인식함.
XML 주석의 작성 규칙
XML 프롤로그(prolog) 부분에는 주석을 작성할 수 없다.
또한, XML 속성의 속성값 내부에도 주석을 작성할 수 없다.
XML 에서는 주석 안에 또 다른 주석을 작성할 수는 없다.
XML 문서 구조
XML 요소 부분은 하나 이상의 XML 요소로 구성된다.
XML 요소
각각의 XML 요소는 하나 이상의 다른 요소를 포함할 수 있다.
또한, 텍스트, 속성, 미디어 객체나 경우에 따라 이들 전부를 포함할 수도 있다.
예제
<?xml version="1.0 encoding="UTF-8"?>
<school>
<lecture category="application">
<java>Java</java>
<cpp>Cpp</cpp>
</lecture>
<lecture category="web">
<php>PHP</php>
<asp>ASP</asp>
</lecture>
</school>
위의 예제에서<java>, <cpp>, <php>, <asp> 요소는 각각 자신만의 텍스트를 가진다.
<school>요소와 <lecture>요소는 다른 요소들을 포함한다.
또한, <lecture>요소는 category라는 속성을 가진다.
XML 요소 문법
XML 요소는 다음과 같은 문법을 사용하여 정의할 수 있다.
문법
<요소이름 속성1="속성값" 속성2="속성값"... > 내용 </요소이름>
또한, 어떠한 내용도 가지지 않는 빈 요소(empty element)는 다음과 같이 정의할 수 있다.
문법
<요소이름 속성1="속성값" 속성2="속성값" ... />
빈 요소는 자신만의 내용을 가지지는 않지만, 요소에 대한 데이터를 저장할 수 있는 속성을 가질 수는 있다.
XML 요소 이름의 작성 규칙
XML 속성
XML 속성은 XML 요소에 대한 추가적인 정보를 제공해주며, 해당 요소의 특징을 정의한다.
XML 속성은 다음과 같은 문법을 사용하여 정의할 수 있다.
문법
<요소이름 속성1="속성값" 속성2="속성값" ... >
XML 요소의 속성은 속성 명="속성값"의 형태로 정의된다.
여기에서 속성값은 반드시 따옴표로 둘러싸여야 한다.
요소와 속성의 차이점
예제 1
<student>
<name>홍길동</name>
<year>3</year>
<major>컴퓨터공학</major>
</student>
예제 2
<student name="홍길동">
<year>3</year>
<major>컴퓨터공학</major>
</student>
위의 두 예제에서 이름(name)이라는 데이터를 하나는 XML 요소로, 하나는 XML 속성으로 표현하고 있다.
결과적으로 이 두 예제는 완전히 같은 정보를 제공한다.
정보의 전달이라는 측면에서 보면 XML 요소로 표현하는 방법과 XML 속성으로 표현하는 방법에 큰 차이는 없다.
하지만 속성은 여러 개의 값을 가질 수 없으며, 요소처럼 손쉽게 확장할 수 없다는 단점을 가진다.
또한, 속성은 XML 트리에 포함되지 않기 때문에 다양한 용도로 활용할 수가 없다.
XML 속성 이름의 작성 규칙
XML 네임스페이스(namespace)
XML 네임스페이스는 XML 요소 간의 이름에 대한 충돌을 방지해 주는 방법을 제공한다.
XML 네임스페이스는 요소의 이름과 속성의 이름을 하나의 그룹으로 묶어주어 이름에 대한 충돌을 해결한다.
이러한 XML 네임스페이스는 URI(Uniform Resource Identifiers)로 식별된다.
XML 요소 간의 이름 충돌
따라서 서로 다른 XML 문서를 통합하려고 할 때 같은 이름을 가진 요소로 인해 충돌이 발생할 수 있다.
예제 1
<body>
<h1>html에서의 제목</h1>
<p>html에서의 단락</p>
</body>
예제 2
<body>
<arm>70</arm>
<leg>110</leg>
</body>
위의 두 예제에서 <body>요소는 서로 완전히 다른 의미로 사용된다.
예제 1에서는 HTML 문서의 <body> 태그로 사용되었다,
예제 2에서는 실제 몸을 의미하여, 각 신체 부위의 치수를 기록하기 위해 사용되었다.
하지만 사용자나 XML 응용 프로그램은 두 <body>요소의 이러한 차이점을 어떻게 다뤄야 하는지 알지 못한다.
XML 네임스페이스의 선언
XML에서는 접두사(prefix)를 이용하여 위와 같은 이름의 충돌을 방지하고 있다.
서로 같은 이름에 요소마다 서로 다른 접두사를 붙이면 이름의 충돌을 방지할 수 있게 된다.
XML에서 이러한 접두사를 사용하려면, 반드시 먼저 접두사에 대한 네임스페이스를 선언해야 한다.
XML에서 네임스페이스를 선언하는 문법은 다음과 같다.
문법
<요소이름 xmlns:prefix="URI">
XML 네임스페이스의 선언은 xmlns나 xmlns:로 시작한다.
prefix 속성값에는 이름 앞에 붙게 되는 네임스페이스 접두사(namespace prefix)를 명시한다.
접두사로 사용되는 URI는 네임스페이스 식별자를 의미한다.
예제
<root>
<a:body xmlns:a="https://www.w3.org/TR/html5/">
<a:h1>html에서의 제목</a:h1>
<a:p>html에서의 단락</a:p>
</a:body>
<b:body xmlns:b="http://codingsam.com/xml/physical/">
<b:arm>70</b:arm>
<b:leg>110</b:leg>
</b:body>
</root>
위의 예제에서 첫 번째 <body>요소의 xmlns 속성은 a:라는 접두사를 선언한다.
두 번째 <body>요소의 xmlns 속성은 b:라는 접두사를 선언한다.
이렇게 XML 요소에 네임스페이스가 선언되면, 해당 요소의 모든 자식(child)요소에도 같은 네임스페이스가 선언된다.
이러한 네이스페이스 선언은 XML 루트(root)요소에서도 선언할 수 있다.
예제
<root
xmlns:a="https://www.w3.org/TR/html5/"
xmlns:b="http://codingsam.com/xml/physical/">
<a:body>
<a:h1>html에서의 제목</a:h1>
<a:p>html에서의 단락</a:p>
</a:body>
<b:body>
<b:arm>70</b:arm>
<b:leg>110</b:leg>
</b:body>
</root>
URI(Uniform Resource Identifiers)
URI란 통합 자원 식별자를 의미하며, 인터넷에 있는 자원을 나타내는 유일한 주소를 의미한다.
URI의 존재는 인터넷에서 요구되는 기본조건으로서 인터넷 프로토콜에도 항상 명시된다.
가장 잘 알려진 URI로는 인터넷 도메인 주소를 나타내는 URL(Uniform Resource Locator)이 있다.
또 다른 URI로는 URN(Universal Resource Name)이 있다.
XML 문서의 종류
문법에 맞는(well-formed) XML 문서
문법에 맞는(well-formed) XML 문서란 XML 문서로서 가져야 하는 최소한의 필수 요건을 충족한 XML 문서를 의미한다.
따라서 이 문서는 XML의 모든 구문을 허용하지만, DTD(document type definition)나 스키마를 사용하지는 않는다.
문법에 맞는(well-formed) XML 문서가 되기 위한 필수 요건은 다음과 같다.
유효한(valid) XML 문서
유효한(valid) XML 문서는 문법에 맞는(well-formed) XML 문서를 좀 더 엄격하게 검증한 문서이다.
따라서 유효한(valid) XML 문서는 모두 문법에 맞는(well-formed) XML 문서이다.
거기에 추가하여 DTD(document type definition)를 가지고 있으며, 그에 따라 제대로 검증된 문서를 의미한다.
XML에서 사용하는 DTD에는 다음과 같이 두 가지 종류가 있다.
XML 파서(parser)
XML 파서(parser)란 응용 프로그램이 XML 문서를 읽을 수 있도록 인터페이스를 제공해주는 라이브러리(library)나 패키지(package)를 의미한다.
XML 파서는 XML 문서가 적합한 형식을 갖추고 있는지와 문법상의 오류는 없는지를 검사한다.
현재 대부분의 주요 웹 브라우저는 모두 XML 파서를 내장하고 있다.
위의 그림은 XML 파서가 어떤 방식으로 XML 문서와 동작하는 지를 보여준다.
XML 파서의 최종 목적은 XML 문서를 응용 프로그램이 읽을 수 있는 코드로 변환하는 것이다.
현재 많이 사용되고 있는 XML 파서의 종류는 다음과 같다.