본문 바로가기
XML

[본문스크랩] 1.4 XML DTD(Data Type Definition)

by 사우람 2010. 7. 12.

1. DTD를 이루고 있는 주요 요소는 문서의 Valid를 검사할때 적용하기 원하는 규칙과

   제약 조건 들 이다. 또한 이름이 있는 엔터티를 선언할 수 있고 외부 파일을 파싱해서

   복합적인 문서(compound document)를 만들 수 있다.

 

2. 엘리먼트

    DTD에 엘리먼트에 관한 정보를 선언할때는 엘리먼트의 이름과 엘리먼트가 가질 수 있는

    컨텐츠 모델을 명시한다.

    <!ELEMENT name content-model>

    EMPTY나 ANY호 시작하지 않는다면 content-model은 반듯이 괄호로 감싸주어야 한다.

    

    Content Model

    

    1) EMPTY : 엘리먼트는 비어있는 엘리먼트여야 하며, 어트리뷰트를 가질 수 있다.

 

    2) #PCDATA : 텍스트 컨탠츠를 가질 수 있으나 자식 엘리먼트는 가질 수 없다.

                        <!ELEMENT Description (#PCDATA)>

 

    3) Element Content

        자식 엘리먼트를 가질 수 있지만 자신의 컨탠츠로 문자를 가질 수 없다.

        자식 엘리먼트를 지정할때는 세 가지 정보를 전달해야 한다.

    

         ① 자식 엘리먼트에 대한 Valid 속성들

 

         ② 자식 엘리먼트들이 나올 수 있는 횟수(mulitiplicity)

 

         ③ 자식 엘리먼트들이 나오는 순서(sequence or ordering)

          

         정보를 전달하는 규칙은 다음과 같다.

 

          ① 자식 엘리먼트로 가능한 여러 엘리먼트들들 "|"를 이용해서 구분해 준다

 

          ② 만약 나오는 순서가 중요하다면 "|"  대신에 ","를 통하여 구분한다.

 

          ③ 자식 엘리먼트의 출현 횟수를 지정하기 위해 EBNF 문자를 이용한다.

               * : 0번이상 나올 수 있다.

               + : 최소한 한번이상 나와야하고 몇번이든 나올 수 있다

               ? : 안나오거나 한번만 나올 수 있다.

               아무것도 지정이 되어있지 않다면 한번만 나온다.

          

          ④ 엘리먼트들을 함게 묶어주기 위해서 괄호를 사용하고 나오는 횟수를 지정하는 기호는

              각 개별요소에 사용할 수도 있고 그룹에 사용할 수도 있다.

 

              <!ELEMENT TroubleTicket (Description?, Customer , Product, Incident)>

              TroubleTicket 엘리먼트는 선택적인 엘리먼트인 Description과 한번씩만

              나오는 Customer, Product, Incident엘리먼트를 갖는다. 

 

    4) Mixed content

        자식 엘리먼트와 문자데이터를 둘다 가질 수 있다.

        <!ELEMENT name (#PCDATA| elements.....)*> 

 

    5) ANY

        well-formed를 만족하는 어떤한 컨탠츠라도 가질 수 있다.

        mixed-content모델과의 차이점은 자식 요소로 올 수 있는 타입을 지정함으로써

        좀더 제한을 할 수 있고 없고의 차이이다.  

 

 3. 어트리뷰트

     DTD를 이용하면 엘리먼트가 가질 수 있는 속성에 관한 제약 조건을 ATTLIST 선언

     부분을 통해 명시해 줄 수 있다.

    

     <!ATTLIST element-name attribute-name type default>

 

       1) default

          

           ① #REQUIRED : 속성값을 반듯이 제공해야 한다.

 

           ② #IMPLIED : 값이 있어도 되고 없어도 되며, 디폴트값은 사용되지 않는다.

 

           ③ value : 디폴트 값이다.

 

           ④ #FIXED value: 속성값이 명시될때는 받듯이 Fixed 값과 일치해야 하며

                                    없을 경우 디폴트 값으로 사용된다.

 

           <!ATTLIST Product Name CDATA #IMPLIED

                                      Rev    CDATA #FIXED "1.0"

                                      Code  CDATA #REQUIRED>

 

           <Product Name="MedEvac" Rev="1.0" Code="537010502" />

           <Product Rev="1.0" Code="537010502" />

           <Product Code="537010502" />

            위의 XML 요소들은 Valid 하다.

 

         2) type

           

            ① CDATA 

                단순한 문자 데이터를 의미하며 "<"와 "&"를 제외한 마크업도 사용이 가능하다.

                엘리먼트 컨탠츠의 종류인 CDATA 색션과는 다르다.

                

 

            ② NMTOKEN

                 CDATA 값에 XML에서 사용할 수 있는 문자만 사용 가능하도록 제한을

                 둔 것이며 공백을 사용할 수 없다.

               

                 <!ATTLIST TroubleTicket ticketID ID #IMPLIED

                                                    PrimaryHelpAgent NMTOKEN #IMPLIED>

 

                 <TroubleTicket ticketID="T746284"

                                       PrimaryHelpAgent="Melissa">

 

             ③ NMTOKENS

                 여러개의 토큰으로 구성되어 있으며 공백으로 구분한다.

 

                <!ATTLIST TroubleTicket ticketID ID #IMPLIED

                                                   PrimaryHelpAgent NMTOKENS #IMPLIED>

 

                <TroubleTicket ticketID="T746284"

                                      PrimaryHelpAgent="Melissa Price">

           

             ④ 열거(Enumeration)

                 속성값에 가능한 것들을 리스트한 것이다.

 

                <!ATTLIST Contact Status (Primary|Alternate) "Alternate">

                 타입이 디폴트 일때 사용하는 법

 

                 <!ATTLIST TroubleTicket Status (Open|Closed|Canceled) #Required

                                                   SpecialReeport(Summary|Detailed) #IMPLIED>

                   IMPLIED 타입일 경우 필요하다면 Summary나 Detailed 을 사용할 수 있다.

 

              ⑤ ID

                  문서 내에서 고유한 엘리먼트를 식별하기 위해 사용하며

                  그 값은 이름이 다른 속성값과 비교했을때도 유일해야 한다.

                  타입은  #IMPLIED나 #REQUIRED를 사용할 수 있다.

 

                 <?xml version="1.0" encoding="UTF-8"?>
                 <!DOCTYPE TicketSet
                 [
                  <!ELEMENT TicketSet (TroubleTicket | ConsultingTicket)*>
                  <!ELEMENT TroubleTicket EMPTY>
                  <!ATTLIST TroubleTicket ticketID ID #IMPLIED>
                  <!ELEMENT ConsultingTicket EMPTY>
                  <!ATTLIST ConsultingTicket ticketID ID #IMPLIED>
                 ]>

                <TicketSet>
                   <TroubleTicket ticketID="T746284"></TroubleTicket>
                   <ConsultingTicket ticketID="T19834"></ConsultingTicket>
                   <TroubleTicket ticketID="T321234"></TroubleTicket>
                </TicketSet>

 

              ⑥ IDRDF

                  문서에있는 ID타입의 값을 참조한다.

 

                  <!ELEMENT Ticket (#PCDATA)>

                  <!ATTLIST Ticket ticketID IDREF #REQUIRED>

                  동적인 문서에 이런 연결을 만드는 이유는 XML을 만들 때 데이터가 실제

                  가지고 있는 성질을 최대한 비슷하게 만들도록 하기 위해서 이다.

                  데이터가 실제로 연결 관계를 가지고 있다면 그 데이터를 나타내는 문서에서도

                  연결관계를 표시해 줄수있는 IDREF를 사용하는 것 이다.

 

  4. 엔터티(Entities)

      숫자를 사용하여 유니코드를 표현하는 엔터티, 이미 정의되어 있는 문자를 참조한는

      엔터티, 문서 안에서 쓰이는 텍스트를 참조하기 위한 일반적인 엔터티가 있다.

      

      내부적 엔터티

      <!ENTITY copy "This text is protected by &#169; copyright">

       이 텍스트는 &copy; 를 통해 문서에서 참조할 수 있다.

 

      외부적인 엔터티

      <!ENTITY copy SYSTEM "copt.xml">

      외부에 정의되어있는 엔터티를 참조한다,

 

      파라미터 엔터티

      DTD자체에서 텍스트를 참조할 수 있는 방법을 제공한다.

       

       ①  부분적 선언

         <!ENTITY % AttImp "CDATA #IMPLIED">    

          완전한 형태의 엘리먼트나 어트리뷰트 선언이 아닌 부분적인 대체로

          외부 서브셋에서 선언되어 참조된다.

 

       ② 전체적인 선언

           <!ENTITY % AttImp "<!ELEMENT ConsultingTicket EMPTY>">
            엘리먼트나 어트리뷰트 전체에 관한 선언으로 DTD 네부에 위치한다.

 

        유지보수와 가독성을 생각하여 파라미터 엔터티의 이름을 정해야 하며

        만약 유지보수와 가독성이 떨어진다면 사용하지 않는것이 좋다.

      

 

5. 노테이션(Notations)

     노테이션은 외부 프로그램과 특정한 타입의 컨텐츠를 결합 시킬 수 있는 메커니즘을

     제공한다. 윈도우에서 파일 확장자명과 특별한 프로그램을 연결시켜 주는 개념과 비슷

     하다고 하겠다.

 

     ① 일반적인 선언

         <!NOTATION rm SYSTEM "realplayer.exe">

          rm이라는 노테이션을 realplay와 연결한다.

 

     ② 외부 셋에서의 사용

         <!ENTITY video SYSTEM "videotest.rm" NDATA rm>

         엔터티를 사용하여 프로그램과 객체를 연결한다.

         이미 선언되어진 노테이션의 경우 NDATA가 이름보다 먼저 나와야 한다.

 

     ③ 어트리뷰트에서의 사용

         <!ATTLIST tester demo ENTITY #IMPLIED>

         <tester demo="video">

          어트리뷰트로 엔터티를 정의하고 엘리먼트에서 사용한다.

 

        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE tester[
           <!NOTATION rm SYSTEM "file:///c:\temp\realplayer.exe">
           <!ENTITY video SYSTEM "videotest.rm" NDATA rm>
           <!ELEMENT tester EMPTY>
           <!ATTLIST tester demo ENTITY #IMPLIED>
         ]>

        <tester demo="video"></tester>

 

       ④  어트리튜트의 열거된 속성으로의 사용

            DTD에 선언된 노테이션이 있는 경우 어트리부트 열거 타입으로 사용할

            수 있다.

            <?xml version="1.0" encoding="UTF-8"?>
            <!DOCTYPE clip[
            <!NOTATION rm SYSTEM "realplayer.exe">
            <!NOTATION au SYSTEM "audioshop.exe">
            <!ELEMENT clip EMPTY>
            <!ATTLIST clip format NOTATION (rm|au) #REQUIRED
                                 file CDATA #REQUIRED>
             ]>

             <clip format="au" file="demo.au"/>

 

             노테이션 rm,au를 정의한후 엔터티 선언 없이 어트리뷰트의 타입으로

             바로 사용가능 하다.