(XML)DTD: 엔티티와 속성


IT Story/Database이야기 2010.07.27 13:17



DTD: 엔티티와 속성

 

 shakeJ 상업적 용도 금지

 

DTD에는 속성과 엔티티를 선언 할 수 있다!

 

엔티티

엔티티란, 데이터 항목을 참조하기 위한 XML의 방법.

DTD에서 선언하며 문서에서 참조를 통해 사용이 된다. 일반 엔티티 참조는 &로 시작하여 ; 으로 끝나게 되며, 파라미터 엔티티는 %로 시작하여 ; 로 끝나게 된다.

이러한 엔티티 참조는 XML처리기에서 파싱될 때 엔티티 자체로 바뀌게 된다.

 

엔티티 : 파라미터 / 일반 엔티티

 

일반 엔티티 : XML문서의 내용에 사용이 된다. But, 파라미터 엔티티는 DTD에서 사용 되며, 기능도 매우 강력하다.

 

즉, DTD에서 엔티티를 선언하며, 엔티티 참조를 통해, 일반 엔티티는 문서의 내용에, 파라미터 엔티티는 DTD에서 사용하게 된다

 

엔티티는 내부 또는 외부에 존재 할 수 있는데, 내부 엔티티는 참조하는 XML문서 내부에서 정의한다. 반면에 외부엔티티는 그내용을 파일 등과 같은 외부자원에서 가져오며, 이들을 참조할 때는 그 내용을 찾을 수 있는 URI를 포함한다. 엔티티는 파싱되거나 파싱되지 않을 수도 있다.

이미 우리는 XML에서 미리 정의되어있는 다섯 가지 일반 엔티티 참조(&lt;, &gt;, &amp;, &quot;, &apos;)를 살펴본 적이 있다. 이는 각자 (< > & " ')의 문자를 나타낸다.

 

 

다섯가지 미리 정의 해놓은 엔티티 참조는 마크업으로 인식되는 특수문자들을 텍스트에서 사용할 때 매우 유리하다.

DTD에서는 자신의 엔티티를 직접 선언할 수도 있다.

 

DTD에서는 자신의 엔티티를 직접 선언 할 수 있다. 구성요소를 선언하는 것과 같이 <!ELEMENT>를 사용하는 것과 같이, <!ENTITY>구성요소를 사용한다.

 

<!ENTITY 이름 정의>로 사용이 된다.

 

가장 단순한 엔티티 정의는 엔티티에 대한 참조를 텍스트로 바꾸는 것이다. 예를 들면 'October 15, 2003'을 저장하기위해 TODAY라는 엔티티를 정의 할 수 있다.

 

<!ENTITY TODAY "October 15,2003">이라 정의 할 수 있다. 이제 우린

&TODAY;로 사용하게 되면, XML처리기에 의해 "October 15,2003"로 바뀌게 된다.

 

 

 

일반 엔티티 와 다르게 파라미터 엔티티는

<!ENTITY % 이름 정의>로 선언 할 수 있다.

 

속성(attribute)

속성은 구성요소에 대한 추가정보를 제공하기 위해 사용이 된다.

속성은 추가정보를 제공하기 위해 시작태그와 빈구성요소의 태그에서 사용하는 이름-값의 쌍을 가리킨다.

<CUSTOMER>태그에 TYPE이라는 이름의 속성을 추가하였다.

<CUSTOMER TYPE = "excellent">

<NAME>

. .. .

</NAME>

</CUSTOMER> 

 

위와 같이, 사용하기 위해서는 미리 속성을 선언해주어야 하는데, 이는

<!ATTLIST>를 사용하여서 선언을 할 수 있다. 다음과 같이 선언을 해 주면 된다.

<!ATTLIST 구성요소_이름

속성_이름 형식 기본_값

속성_이름 형식 기본_값

속성_이름 형식 기본_값

속성_이름 형식 기본_값>

<!ATTLIST CUSTOMER

TYPE CDATA #IMPLIED>

 

<CUSTOMER TYPE = "excellent">

 

내부 일반 엔티티 만들기

아까 처음에 기본예와 같이,

와 같이 내부에서 엔티티를 선언하고 참조하는 방식이다.

특징은 일반 참조는 다음과 같이 중첩하여 사용이 가능하다.

<!ENTITY NAME "Alfred Hitchcock">

<!ENTITY SIGNATURE "&NAME; 14 Mystery Drive">

은 가능하지만

<!ENTITY NAME "Alfred Hitchcock &SIGNATURE;">

<!ENTITY SIGNATURE "&NAME; 14 Mystery Drive">

은 불가능하다. 위에서도 참조하고 밑에서도 참조하는 경우는 XML처리기의 예외를 예측할 수가 없다.

이경우는 XML처리기는 &NAME;을 참조하려고 하면 SIGNATURE엔티티의 텍스트를 찾게 되고 다시 SIGNATURE은 NAME의 텍스트를 찾게 되고 ㅜㄴ환이 되어, 순환적인 엔티티 참조는 유효한 문서를 잘못된 문서로 만들게 된다.

 

일반 엔티티 참조는 문서 자체가 아닌 DTTD에서만 사용 되는 텍스트를 삽입하기 위해서 사용할 수가 없다. 예를 들어,

<!ENTITY TAGS "(NAME, DATE, ORDERS)"

<!ELEMENT CUSTOMER &TAGS;> 

 

외부 일반 엔티티 만들기

엔티티는 외부에 존재할 수가 있는데 이럴땐, XML처리기에서 외부의 엔티티를 찾을 수 있도록, 정해주어 참조할 수 있다. 이때에 외부 엔티티는 파싱되어서는 안 된다. DTD처럼 외부 엔티티는 SYSTEM또는 PUBLIC키워드를 사용하여 선언 할 수 있다.

차이점은 SYSTEM의 경우엔 특정 조직에서 별도의 용도로 사용되며,

PUBLIC으로 선언한 엔티티는 공식적인 공용 식별자를 필요로 한다.

 

<!ENTITY 이름 SYSTEM URI>

<!ENTITY 이름 PUBLICK FPI URI>

 

예를 들어, EX.xml이라는 파일에 "October 15, 2003"이라는 날짜가 텍스트로 저장되어 있다고 가정하자. 아래는 그 외부 파일에서 TODAY라는 이름의 엔티티를 구성하는 방법이다.

<!ENTITY TODAY SYSTEM "ex.xml">

 

이렇게 참조를 해놓고 마음대로 TODAY로 데이터 삽입이 가능하다.

 

 

조각들을 이용하여 문서만들기

외뷰부의 엔티티를 사용하는 한가지 방법으로, 여러 조각들을 사용하여 문서를 구성하기도 한다. 예를 들어 ex3.xml을 참조한다고 하면,

ex3.xml

<CUSTOMER>

<NAME>

….

</NAME>

<DATE> </DATE>

<ORDERS>

…..

……

</ORDERS>

</CUSTOMER> 

이라는 내용이 포함되어있는 XML 문서가 존재할 때,

EX111.xml 이라는 파일에서는

<?xml version="1.0" standalone-"no"?>

<!DOCUMENT DOCUMENT [

<!ELEMENT DOCUMENT(CUSTOMER)*>

<!ELEMENT CUSTOMER(NAME,DATE,ORDERS>

<!ELEMENT DATE (#PCDATA)>

<!ENTITY data SYSTEM "ex3.xml">

]>

<DOCUMENT>

&data;

 

</DOCUMENT> 

 

 

내부 파라미터 엔티티 만들기

일반 엔티티는 DTD에서 사용이 불가능하기에 파라미터 엔티티를 사용해야 한다. 파라미터 엔티티 참조는 일반 엔티티 참조는 &가 아닌 %로 시작을 한다.

파라미터 엔티티는 아래와 같이 %만 들어가게 된다.

 

<!ENTITY % 이름 정의>

 

예를 들게 되면,

<?xml version="1.0" standalone ="yes"?>

<!DOCTYPE DOCUMENT [

<!ENTITY % BR "<!ELEMENT BR EMPTY>">

<!ELEMENT …>

<…>

%BR;

]> 

 

<!ENTITY % record "(NAME,DATE,ORDERS)">

<!ELEMENT DOCUMENT (CUSTOMER | BUYER | DISCOUNTER)*>

<!ELEMENT CUSTOMER %record;>

<!ELEMENT BUYER %record;>

<!ELEMENT DISCOUNTER %record;>

<!ELEMENT NAME (LAST_NAME, FIRST_NAME)>

<!ELEMENT LAST_NAME (#PCDATA)>

<!ELEMENT FIRST_NAME (#PCDATA)>

 

<?xml version="1.0" standalone="no"?>

<!DOCTYPE DOCUMENT SYSTEM "xmlenti.xml">

<DOCUMENT>

<CUSTOMER>

<NAME>

<LAST_NAME> </LAST_NAME>

<FIRST_NAME> </FIRST_NAME>

</NAME>

</CUSTOMER>

</CUSTOMER>

 

INCLUDE와 IGNORE 사용하기

DTD의 일부분을 포함 또는 제외하는데 사요이 된다

 

<![INCLUDE [DTD구역]]>과 <![IGNORE [DTD구역]]>의 형식으로     사용이 된다.

<![INCLUDE [

<!ELEMENT PRODUCT_ID (#PCDDATA)>

]]>

여기서 이 명령어들이 왜 중요한지 궁금 할 것이다. 이 경우에는 DTD의 일부 구역을 감추기 위해서 사용을 한다.

<!ENTITY % include "INCLUDE">

…..

<![%includer; [

<!ELEMENT PRODUCT_ID (#PCDDATA)>

]]>

 

이제는 includer의 엔티티 값을 바꾸기만 하면, DTD에서 지정된 구역을 포함시키거나 제외 시킬 수 있다(대용량의 xml의 경우 편리)

 

DTD에서 속성 선언하기

XML에서 속성과 그 형식을 선언하는 것은 매우 유효하다. 문서가 유효하길 바란다면 사용하는 모든 속성들은 이전에 미리 선언해놓아야만 한다.

앞에서 살펴 보았듯, <!ATTLIST> 구성요소를 통해 속성 목록을 선언하게 된다.

 

-CDATA : 단순한 문자데이터 ( 즉, 아무런 마크업을 포함하지 않는 텍스트 )

-ENTITES : 다중엔티티 이름, 공백으로 구분

-ENTITY : 엔티티 이름 (DTD에 선언되어있어야 함)

-ID : 고유해야 하는 적절한 XML이름 ( 즉, ID 형식으로 다른 속성과 공유되면 안됨,)

 

<![INCLUDE [

<!ELEMENT PRODUCT_ID (#PCDDATA)>

]]>

 

#REQUIRED

 

속성의 기본값으로 #REQUIRE을 사용하게 되면, 기본값을 직접 지정하지는 않지만, 그 DTD를 이용하는 사람이 지정해야만 한다.

<?xml version="1.0" standalone-"no"?>

<!DOCUMENT DOCUMENT [

<!ELEMENT DOCUMENT(CUSTOMER)*>

<!ELEMENT CUSTOMER(NAME,DATE,ORDERS>

<!ELEMENT DATE (#PCDATA)>

<!ATTLIST CUSTOMER

OWES CDATA #REQUIRED>

]>

<DOCUMENT>

<CUSTOMER OWES="$0">

<NAME>

</CUSTOMER>

<CUSTOMER OWE="&55">

</CUSTOMER>

 

#IMPLIED

required와 다르게 기본값으로 지정할것이 없으며, 문서의 작성자들도 전혀 이 속성을 사용할 필요가 없는 경우 사용되며, xml처리기는 이 속성이 사용되지 않아도 문제가 발생하지 않는다. 따라서 반드시 포함시킬 필요는 없다.

<?xml version="1.0" standalone-"no"?>

<!DOCUMENT DOCUMENT [

<!ELEMENT DOCUMENT(CUSTOMER)*>

<!ELEMENT CUSTOMER(NAME,DATE,ORDERS>

<!ELEMENT DATE (#PCDATA)>

<!ATTLIST CUSTOMER

OWES CDATA #IMPLIED>

]>

<DOCUMENT>

<CUSTOMER OWES="$0">

<NAME>

</CUSTOMER>

<CUSTOMER OWE="&55">

</CUSTOMER> 

 

#FIXED

속성들이 항상 고정된 값을 갖도록 구성할 수 있다. 이를 위해서는 #FIXED를 사용한다.

아래 예에서는 영어만을 사용했으므로 LANGUAGE속성으로 EN을 지정하였다.

<?xml version="1.0" standalone-"no"?>

<!DOCUMENT DOCUMENT [

<!ELEMENT DOCUMENT(CUSTOMER)*>

<!ELEMENT CUSTOMER(NAME,DATE,ORDERS>

<!ELEMENT DATE (#PCDATA)>

<!ATTLIST CUSTOMER

OWES CDATA #FIXED "EN">

]>

<DOCUMENT>

<CUSTOMER >

<NAME>

</CUSTOMER>

<CUSTOMER>

</CUSTOMER> 

 

속성형식

 

- CDATA

가장 간단한 속성 형식이 CDATA이며, 이것은 간단한 문자데이터를 가리킨다. 즉, 마크업을 포함하지 않기만 한다면, 속성에는 모든 문자열을 값으로 지정할 수 있다. 한가지 유의해야 할 것은 마크업을 사용할 수 없으며, <, " 등의 문자들을 포함하는 문자열을 사용할 수 없다. 이들 문자를 사용하려면 미리 정의되어 있는, 엔티티 참조를 사용해야 한다. 이들 엔티티 참조는 문서가 파싱될 때, 해당 문자들로 바뀌게 된다.

(PCDATA는 이미 파싱을 거친 문자들이고, CDATA는 파싱 처리기가 파싱을 한다. )

 

- 나열형

<?xml version="1.0" standalone-"no"?>

<!DOCUMENT DOCUMENT [

<!ELEMENT DOCUMENT(CUSTOMER)*>

<!ELEMENT CUSTOMER(NAME,DATE,ORDERS>

<!ELEMENT DATE (#PCDATA)>

<!ATTLIST CUSTOMER

CREDIT_OK (TRUE | FALSE) "TRUE">

]>

<DOCUMENT>

<CUSTOMER CREDIT_OK = "FALSE" >

<NAME>

</CUSTOMER>

<CUSTOMER>

</CUSTOMER> 

위 예제의 경우 나열형은 다른 속성 형식 처럼 키워드를 사용하지 않고, 사용할 수 있는 값들의 목록을 지정한다.. 위에선 TURE, FALSE를 나열하여, 기본값은 TRUE로 지정해주고 있다.

 

- ID

또 다른 매우 중요한 속성 형식으로 ID가 있다. XML에서는 내부 응용 프로그램에서 구성요소를 구분하기 위해 ID를 사용하기 때문에, 구성요소의 ID값은 매우 특별하다. XML처리기는 문서에서 ID형식이 같은 구성요소가 두 개 존재 할 수 없다는 것을 알고 있다.

<?xml version="1.0" standalone-"no"?>

<!DOCUMENT DOCUMENT [

<!ELEMENT DOCUMENT(CUSTOMER)*>

<!ELEMENT CUSTOMER(NAME,DATE,ORDERS>

<!ELEMENT DATE (#PCDATA)>

<!ATTLIST CUSTOMER

CUSTOMER_ID ID #REQUIRED>

]>

<DOCUMENT>

<CUSTOMER CUTOMER_ID = "C123124" >

<NAME>

</CUSTOMER>

<CUSTOMER CUTOMER_ID ="C1241242">

</CUSTOMER>

 

ID값은 적절한 이름으로 구성되어야 한다 – 숫자로 시작할 수 없으며 단순한 숫자는 사용불가(1234)같은.

 

- IDREF

IDREF 속성 형식은 문서의 구조에 대한 내용을 지정하기 위해 속성을 사용하고자 할 때 지정한다. 특히, 구성요소들 사이의 관계에 대한 내용을 지정하기 위해 사용한다. IDREF속성은 문서의 다른 구성요소에 대한 ID값을 저장한ㄷ.

<?xml version="1.0" standalone-"no"?>

<!DOCUMENT DOCUMENT [

<!ELEMENT DOCUMENT(CUSTOMER)*>

<!ELEMENT CUSTOMER(NAME,DATE,ORDERS>

<!ELEMENT DATE (#PCDATA)>

<!ATTLIST CUSTOMER

CUSTOMER_ID ID #REQUIRED

EMPLOYER_ID IDREF #IMLIED>

]>

<DOCUMENT>

<CUSTOMER CUTOMER_ID = "C123124" >

<NAME>

</CUSTOMER>

<CUSTOMER CUTOMER_ID ="C1241242" EMPLOYER_ID =" "C123124" >

</CUSTOMER>

 

 

- NONATION

이 형식의 속성을 선언하면, Notation으로 선언된 속성의 값을 지정할 수 있다.

Notation은 비 xml데이터 형식을 가리키며, 외부 엔티티를 나타내기 위해 사용된다. 대표적인 형식으로 image/gif, application/xml , text/html등의 형식이 있다.

 

notation을 선언하려면, 다음과 같이 DTD에서 <!NOTATION>구성요소를 사용한다

 

<!NOTATION 이름 PUBLIC FPI "외부 ID>

 

로 선언하면된다.

<?xml version="1.0" standalone-"no"?>

<!DOCUMENT DOCUMENT [

<!ELEMENT DOCUMENT(CUSTOMER)*>

<!ELEMENT CUSTOMER(NAME,DATE,ORDERS>

<!ELEMENT DATE (#PCDATA)>

<!NOTATION GIF SYSTEM "image/gif"> <~이렇게 gif나 jpeg둘 중 선택을 해서 만들 수 있다.

<!ATTLIST CUSTOMER

IMAGE NMTOKEN #IMPLIED

IMAGE_TYPE NATATION (GIF | JPG) #IMPLIED>

]>

<DOCUMENT>

<CUSTOMER IMAGE="image.gif" IMAGE_TYPE="GIF">

<NAME>

</CUSTOMER>

<CUSTOMER>

</CUSTOMER>

 

문서에 비 xml 데이터 삽입하기

image.gif를 실제 문서의 일부분으로 만들기 위해서는, image.gif를 외부의 파싱되지 않는 엔티티로 처리하면 된다. xml을 텍스트 이외의 데이터를 저장하기 위한 수단으로 나온 것이 아니다. 이 때문에, XML이 아닌 비 XML데이터를 XML문서와 연결하기 위해 파싱 되지 않은 엔티티를 처리 할 수 있는 아이디어를 새로 추가하였다.

<?xml version="1.0" standalone-"no"?>

<!DOCUMENT DOCUMENT [

<!ELEMENT DOCUMENT(CUSTOMER)*>

<!ELEMENT CUSTOMER(NAME,DATE,ORDERS>

<!ELEMENT DATE (#PCDATA)>

<!NOTATION GIF SYSTEM "image/gif">

<!ENTITY SNAPSHO1 SYSTEM "image.gif" NDATA GIF> image.gif라는 외부이미지 참조하기 위해 외부의 파싱되지 않는 엔티티를 만들었다.

<!ATTLIST CUTOMER

IMAGE ENTITY #IMPLIED>

XML 문서에 직접 삽입할 수는 없다. 대신에 ENTITY형식의 새로운 속성을 만들어준다.

]>

<DOCUMENT>

<CUSTOMER IMAGE="SNAPSHOT1">

</CUSTOMER>

</DOCUMENT>

 

저작자 표시 비영리
신고

WRITTEN BY
ShakeJ

0 ,