본문 바로가기

Back/XML

XML 간단하게 알아보기 - 5 (DTD)

XML 작성하는 방법은 이미 다 알아봤다. 문제는 그게 "잘 만들어진" XML 문서인지 공증을 받아야 가치가 있다.

잘 만들어진 XML 문서에는 두 가지 레벨이 존재한다.

 

  • Well Formed
  • Valid

 

Well Formed:

"형식을 잘 지킨 XML 문서"라는 뜻이다. 태그를 잘 닫고, 앞뒤 태그의 이름을 동일하게 맞추고, XML 선언문을 잘 사용하고...

즉, 문법을 잘 지켰다는 의미다.

하지만 문법을 잘 지켰다고 그게 잘 만든 문서라고 하지는 않는다.

 

Valid:

Well Formed인 문서이면서, 해당 문서에는 Data Type에 대한 정의가 존재한다는 뜻이다.

데이터 타입에 대한 정의는 DTD 문서 혹은 XML Schema 방식으로 증명할 수 있다.

간단한 예시로 알아보자.

 

<?xml version="1.0" encoding="utf-8"?>
<league>
    <champion>
    	<position>AD Carry</position>
        <name>Ezreal</name>
    <champion>
</league>

 

이 문서는 게임을 즐기는 사람이라면 어렵지 않게 이해할 수 있는 문서다. 

하지만, 게임에 전혀 관심이 없는 사람이라면 어떨까? 하나도 이해를 못하지 않을까?

 

이처럼, 각종 문서는 해당 분야에 전문적인 지식을 내포하는 경우가 많다.

게임처럼 대중적인 것이 아니라, 핵융합 연료 전지를 만들기 위한 연료 조합의 재료에 대한 정보를 담는다고 가정해보자.

 

일반적으로 그 용어를 이해할 수 없을 것이다.

그래서 해당 문서에서 정의한 element에 대해서 다른 사람들도 이해할 수 있도록 데이터 타입이 무엇을 의미하는지 적어놓은 것이 DTD, Data Type Definition 이라고 볼 수 있다.

 

DTD는 별도의 문서로 작성된다. 그리고 작성한 문서를 해당 정의를 사용하는 곳에서 참조한다.

다음을 보자.

 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE league SYSTEM "League.dtd">

<league>
    <champion>
    	<position>AD Carry</position>
        <name>Ezreal</name>
    <champion>
</league>

 

XML 선언문 아래에 문서 유형을 정의하는 문이 들어갔다. 해석을 하면 다음과 같다.

 

  • !DOCTYPE league = league라는 데이터 타입이 무엇인지는
  • SYSTEM "League.dtd" = League.dtd 라는 파일에 정의되어 있습니다.

 

그렇다면 이제 dtd 형식의 문서가 무엇인지 궁금해진다.

다음을 보자.

 

<!-- League.dtd -->

<!DOCTYPE league [
<!ELEMENT champion (position, name)>
<!ELEMENT position (#PCDATA)>
<!ELEMENT name (#PCDATA)>
]>

 

champion, position, name에 대한 정의가 들어있다.

league는 최상단에 선언되어 root element임을 알리고 있다.

champion은 position, name을 내포하는 child이며

position, name은 #pcdata라는 형식으로 값을 표현하는 subchild라고 표현하고 있다.

 

문법이나 그렇다고 치지만, #PCDATA가 무엇인지 전혀 알 수가 없다.

해당 문법은 XML parser가 읽을 수 있는 character data임을 표시하는 것이다.

간단하게, 앞서 봤던 &lt; 이런 문법을 < 으로 치환이 가능하다는 것을 XML Parser에게 알려주는 것이다.

 

<!ELEMENT >는 유추가 가능하듯, 해당 요소가 element라는 것을 명시하는 것이다.

root element는 별도로 !DOCTYPE으로 표현하는 것이고.

 

#PCDATA 외에도 #CDATA가 존재한다.

#PCDATA는 XML Parser가 해석한 결과본을 보여주지만,

#CDATA는 XML Parser가 해석하지 않고 원본 그대로 전달한다.

 

추가적으로, element 외에도 entity라는 요소를 사용할 수도 있다.

entity는 쉽게 말하자면 변수다. entity로 무언가를 선언하고, 해당 값을 할당하면, 나중에 선언한 명칭만 불러오면 해당 값을 XML Parser가 출력한다.

다음을 보자.

 

<!-- Troll.dtd -->

<!DOCTYPE league [
<!ENTITY Yumi "Troll Elite">
<!ENTITY Ezreal "Troll Leader">
]>

 

이렇게 선언한 dtd 문서가 존재한다.

이것을 참조하여 사용할 수 있다.

다음을 보자.

 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE league SYSTEM "Troll.dtd">

<league>
    <champion>
    	<position>AD Carry</position>
        <name>&Ezreal;</name>
    <champion>
</league>

 

<name> Ezreal </name> 파트에 어떤 것이 출력될지 상상이 되는가?

그것은 진리가 아닐까?