XML 입문 | DTD를 사용하여 XML 구조의 정의 | DTD에서 요소의 작성 횟수 지정

각 요소의 작성 가능 횟수에 대해 DTD로 지정하는 방법에 대해 설명한다.

우선 지금까지의 페이지에서 사용하던 아래의 XML 문서를 다시 보도록 하자.

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 재고정보[
    <!ELEMENT 재고정보 (상품)>
    <!ELEMENT 상품 (이름, 개수)>
    <!ELEMENT 이름 (#PCDATA)>
    <!ELEMENT 개수 (#PCDATA)>
]>

<재고정보>
    <상품>
        <이름>자전거</이름>
        <개수>20</개수>
    </상품>
</재고정보>

이 XML 문서는 “상품” 요소가 하나만 작성되어 있지만, 데이터를 추가하고 다음과 같이 두 번째 “상품” 요소를 추가할 수도 있다.

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 재고정보[
    <!ELEMENT 재고정보 (상품)>
    <!ELEMENT 상품 (이름, 개수)>
    <!ELEMENT 이름 (#PCDATA)>
    <!ELEMENT 개수 (#PCDATA)>
]>

<재고정보>
    <상품>
        <이름>자전거</이름>
        <개수>20</개수>
    </상품>
    <상품>
        <이름>책장</이름>
        <개수>12</개수>
    </상품>
</재고정보>

XML 문서로만은 문제 없겠지만, 이 문서를 XML Validator에서 검증해 보면 아래와 같이 에러가 발생한다.

[ERROR] The content of element type "재고정보" must match "(상품)".

그럼 DTD 부분을 아래와 같이 변경하여 사용해 보도록 하자. “재고정보"의 괄호 안에 있는 “상품"에 “+“가 추가가 되었다.

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 재고정보[
    <!ELEMENT 재고정보 (상품+)>
    <!ELEMENT 상품 (이름, 개수)>
    <!ELEMENT 이름 (#PCDATA)>
    <!ELEMENT 개수 (#PCDATA)>
]>

<재고정보>
    <상품>
        <이름>자전거</이름>
        <개수>20</개수>
    </상품>
    <상품>
        <이름>책장</이름>
        <개수>12</개수>
    </상품>
</재고정보>

이 XML 문서를 XML Validator에서 검증해 보면 에러가 없다는 것을 확인할 수 있다.

No errors found.

이번에는 XML 자체만으로는 문제가 없었다.

앞에서 설명을 하지 않았는데, DTD에서 요소의 모델을 정의 할 때, 뭔가 추가로 작성이 되지 않는다면 그 요소는 그 요소를 포함하고 있는 부모 요소의 내부에 한번밖에 작성할 수 없다는 규칙이 있다.

첫 번째 예제에서는 “상품” 요소는 작성 가능 횟수를 작성하지 않았기에 “상품"요소의 부모 요소인 “재고정보” 요소 안에 두번 작성이 되어 에러가 발생하였다.

두 번째 예제에서는 “상품"요소 모델에 “+“를 추가로 기입되어 있다. “+“는 발생 횟수가 “1회 이상 발생한다"라는 뜻을 나타내는 기호여서 “상품"요소가 두번 작성이 되어서도 에러는 발생하지 않았다.

추가적으로 “상품” 요소에 포함된 “이름"과 “개수” 요소은 XML 문서 전체에서 보면 여러 번 포함하고 있지만, 각각의 부모 요소 (여기서는 모두 “고객"요소) 안에 한 번씩만 포함되지 않았기에 문제가 없었다.

요소의 작성 횟수 지정 방법

그럼, 요소의 작성 횟수 지정 방법에 대해서 알아보겠다. 작성 회수을 지정하는 기호는 다음과 같다.

기호 작성 가능 횟수
+ 1회 이상
? 0회 또는 1회
* 0회 이상
지정 없음 1회만

이 기호들은 요소 모델의 오른쪽에 작성한다. 형식은 다음과 같다.

<!ELEMENT 요소명 (요소명1기호)>
<!ELEMENT 요소명 (요소명1기호, 요소명2기호, ...)>
<!ELEMENT 요소명 (요소명1기호, 요소명2기호, ...)기호>

예를 들면,

<!DOCTYPE 재고정보[
    <!ELEMENT 재고정보 (상품+)>
    <!ELEMENT 상품 (이름, 개수, 상세정보?)>

그럼 다른 샘플을 확인해 보도록 하자. 지금까지의 샘플에 “색상"이라는 요소를 추가하고 이 요소는 0번 이상 출현할 수 있도록 정의해 한다.

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 재고정보[
    <!ELEMENT 재고정보 (상품+)>
    <!ELEMENT 상품 (이름, 개수, 상세정보?)>
    <!ELEMENT 이름 (#PCDATA)>
    <!ELEMENT 개수 (#PCDATA)>
    <!ELEMENT 상세정보 (무게, 색상*)>
    <!ELEMENT 무게 (#PCDATA)>
    <!ELEMENT 색상 (#PCDATA)>
]>

<재고정보>
    <상품>
        <이름>자전거</이름>
        <개수>20</개수>
        <상세정보>
            <무게>12Kg</무게>
        </상세정보>
    </상품>
    <상품>
        <이름>책장</이름>
        <개수>12</개수>
        <상세정보>
            <무게>20Kg</무게>
            <색상>검정</색상>
            <색상>회색</색상>
        </상세정보>
    </상품>
</재고정보>

“색상"요소는 0회 이상 여러번 작성할 수 있다. 그러므로 첫 번째 “상품” 요소인 자전거는 “색상"이 한 번도 나오지 않지만, 두번째 “상품"요소는 “색상” 요소는 여러 번 작성이 되어 있다.

위에 정리가 된 테이블에 내용대로 기호를 지정하지 않는 경우의 발생 빈도는 “1회 작성"이 되므로 반드시 한 번은 작성되어야 한다. 선택적 요소인 경우에는 ?또는 *를 기입 되어야 한다는 것을 기억하도록 하자.




최종 수정 : 2019-10-07