본문으로 바로가기

명세서 읽는 방법

category Dev Environment/개발 기타 자료 2016. 8. 9. 10:25

명세서

DTD에 표시된 URI(예: loose.dtd 또는 xhtml1-transitional.dtd)를 내려받아서 명세를 한 번이라도 열어보신 분들이라면 알 수 없는 낯선 문자들에 대한 당혹스러움을 감출 수 없었을 것입니다. 

HTML/XHTML의 문법 규칙들이 포함되어 있고 브라우저가 이것을 어떻게 해석해야 하는지에 대한 단서가 기록되어 있습니다. 만약 DTD가 없다면 여러분은 <address> 요소 안쪽에 어떤 요소가 허용되는지 알 수 없을 것입니다.

<address> 요소 안쪽에는 블럭 요소를 허용하지 않지만 예외적으로 HTML 4.01 호환 모드(Transotional) DTD에서 블럭 요소인 <p> 요소를 허용합니다.

문법 검사기(HTML Validator)는 DTD를 근거로 문법을 검사하기 때문에 호환 모드에서 <address> 요소 안쪽의 <p>를 적법하다고 간주하며 HTML 4.01 엄격 모드(strict.dtd)에서는 적법하지 않다고 오류 메시지를 보여줄 것입니다.

DTD는 HTML/XHTML 문서에 대한 가장 기초적인 명세로써 웹 브라우저가 HTML을 해석하는 기준이 되고 문법 검사기가 유효성을 판단하는 기준이 됩니다. 





Read DTD smart

지금부터는 이해를 돕기 위하여 HTML 4.01 호환모드 DTD인 http://www.w3.org/TR/html4/loose.dtd 파일을 내려받은 후 화면에 열어놓거나 또는 웹 페이지 버전의 HTML 4.01 loose.dtd 페이지(추천) 또는 웹 페이지 버전의 XHTML 1.0 – DTDs(추천)을 열어놓은 다음 이 글과 번갈아 보면서 내용을 천천히 정독해 주시기 바랍니다. 

HTML 4.01 Transitional DTD를 기준으로 설명하겠습니다. 

이 포스트의 내용은 조금 어렵지만 몇가지 낮선 단어들과 규칙들을 익힘으로써 HTML과 XHTML 명세를 다른 사람에게 물어보지 않고도 스스로 터득할 수 있는 근본적인 지식이 될 것입니다.



명세의 시작과 끝

DTD에서 HTML 요소 및 속성에 대한 명세 구문은 여는 꺽쇠와 느낌표(<!)로 시작하여 닫는 꺽쇠(>)로 끝납니다.

<! 이곳에 명세가 들어갑니다 >



명세의 주석

명세의 주석은 — 2회 연속 작성된 하이픈 — 문자 안쪽에 기술합니다. 주석 안쪽에 포함된 내용은 기계적으로 해석되지 않고 사람이 읽을 수 있도록 자연어 문장으로 처리되어 있습니다. 아래 첫 번째 주석은 순수한 주석문이고 두 번째 주석은 명세 안에 포함된 주석문 입니다. 주석은 한 줄 또는 여러줄이 될 수 있습니다.

<!– 이곳에 주석의 내용이 들어갑니다 –>

<! 이곳에 명세가 들어갑니다 — 이곳에 주석의 내용이 들어갑니다 –>



연산 기호들

연산 기호들은 주로 특정 요소가 자식 요소로써 어떤 요소들을 어떻게 허용하는지 정의할 때 사용합니다. 예를 들어 <a> 요소는 다른 인라인 요소들은 모두 허용하지만 예외적으로 자신과 동일한 요소인 <a> 요소만은 자식으로 둘 수 없다고 -(A) 선언되어 있는데 이러한 선언은 모두 연산자를 통해 표시 됩니다. 


  • ( … ) : 연산 그룹의 범위
  • A : A는 필수적이며 한 번만 사용할 수 있다
  • A+ : A는 필수적이며 한 번 이상 사용해야 한다
  • A? : A는 생략하거나 한 번만 사용할 수 있다
  • A* : A는 생략하거나 한 번 이상 사용할 수 있다
  • +(A) : 추가적으로 A를 사용할 수 있다
  • -(A) : 예외적으로 A는 사용할 수 없다
  • A | B : A 또는 B를 사용할 수 있다
  • A, B : A 그리고 B는 순서를 지켜야 한다
  • A & B : A 그리고 B는 순서에 무관하다



등장하는 용어들

# PCDATA(Parsed Character Data)

XML 해석기에 의하여 해석되는 문자 데이터를 의미 합니다. 텍스트와 HTML 요소들을 있는 그대로 브라우저로 보내는 것이 아니라 적절하게 렌더링하기 위하여 변환합니다. 예를 들면 ‘<, >’ 기호는 요소의 시작 또는 끝으로 해석하고 ‘&’ 기호는 HTML 문자의 본체(Entity)가 시작되는 것으로 간주 합니다. 따라서 #PCDATA 안쪽에서 ‘&’ 기호를 해석하지 않고 화면에 그대로 표시하려면 HTML Entity 형식을 빌어 ‘&amp;’ 와 같이 작성해야 합니다.


# CDATA(Character Data)

XML 해석기에 의하여 해석되지 않는 문자 데이터를 의미 합니다. CDATA 안쪽에서 표기하는 모든 문자는 해석기가 해석하지 않기 때문에 브라우저에 그대로 전달 됩니다. 부등호(<, >)와 연산자(&) 사용이 많은 <script> 요소 안쪽에서 웹 브라우저가 이 기호들을 HTML 요소 또는 Entity가 시작되는 것으로 오해하는 것을 예방하기 위하여 CDATA 형식을 선언 <![CDATA[ … ]]> 하기도 합니다.


# REQUIRED

반드시 요구되는.


# IMPLIED

생략 가능한. (생략하는 대신 웹 브라우저가 기본 값을 제공하거나 부모로부터 상속을 받기도 함)


# FIXED

주어진 값만 사용할 수 있는.



본체와 변수

DTD에서는 본체(Entity)와 변수(Parameter) 개념을 사용합니다. 

본체란 변수의 실체(원래 모습)이며 변수는 본체를 대체하는 문자 입니다. <!ENTITY> 구문 안쪽에 선언된 내용들은 본체와 변수에 관한 선언 입니다.

<!ENTITY %  변수 이름  "변수의 실체">


예를 들어 <h1>~</h6> 요소는 %heading; 이라는 변수 이름의 실체 입니다. 

<h1>~<h6> 요소는 각각의 이름만 다를 뿐 각각의 요소는 모두 동일한 속성과 콘텐츠 모델(자식 요소)을 갖습니다. 

DTD에서는 같은 내용을 일일이 반복해서 열거하는 것을 피하기 위하여 <h1>~</h6> 요소에 대하여 %heading; 이라는 변수를 선언했습니다. 

%heading;에 대한 실체는 문서 상단에 한 번 선언해 놓고 본문에서는 <h1>~<h6> 요소 대신에 %heading; 이라는 변수를 사용합니다. 


다음 구문은 %heading; 이라는 변수와 본체를 선언하는 구문 입니다.

<!ENTITY % heading "H1|H2|H3|H4|H5|H6">


다음 구문은 DTD 본문에서 %heading; 이라는 변수를 사용한 예 입니다. 

퍼센트 ‘%‘ 기호로 시작하여 세미콜론 ‘;‘ 기호로 끝나는 것은 모두 변수이며 모든 변수들은 각각의 실체에 해당하는 본체가 문서 상단에 기술되어 있습니다. 

(%heading;)의 본체는 (H1|H2|H3|H4|H5|H6) 이므로 아래 구문은 <h1>~<h6> 요소의 명세를 기술하는 구문 입니다.

<!ELEMENT (%heading;)>



요소와 속성

요소에 대한 명세는 <!ELEMENT> 안쪽에 선언되고 이 요소의 속성에 대한 명세는 <!ATTLIST> 안쪽에 선언 됩니다. 

<!ELEMENT> 구문이 등장하면 곧 관련된 <!ATTLIST> 구문이 자연스럽게 등장합니다.

<!ELEMENT 이곳에 요소의 명세가 들어갑니다>

<!ATTLIST 이곳에 속성의 명세가 들어갑니다>


요소 명세 읽기

요소의 명세는 다음과 같은 순서로 기술하는데 띄어쓰기를 이용해서 각각을 구분 합니다.

<!ELEMENT  요소 이름  시작 명세  종료 명세  자식 명세  — 주석 –>

‘시작 명세’와 ‘종료 명세’는 단순히 태그가 ‘필수(-)’적인지 또는 ‘생략(O)’할 수 있는지를 선언합니다. ‘자식 명세’는 다른말로 표현해서 ‘허용하는 자식 요소의 형태’라고 이해해도 됩니다. 


조금 더 구체적으로 이해하기 위하여 문단을 의미하는 <p> 요소의 명세를 보여 드리겠습니다. 

<!ELEMENT P – O (%inline;)* — paragraph –>

<p> 요소의 명세를 사람이 이해할 수 있는 자연어로 번역하면 다음과 같습니다. 

%inline; 이라는 변수가 연산을 위한 괄호() 안에 포함되었고 별표 연산자 ‘*’를 통해서 몇 번 사용할 수 있는지도 설명 되었습니다.

P 요소는 시작 태그가 반드시 필요(-)하고 종료 태그는 선택적(O)이다.

인라인 콘텐츠만(%inline;)을 자식으로 가질 수 있는데 이를 생략하거나 한 번 이상 사용(*)할 수 있다. 

— 문단을 의미한다. —


<p> 요소에 대하여 웹 브라우저 또는 문법 검사기는 다음과 같이 해석할 것입니다.

  • ELEMENT : 요소에 관한 명세임
  • P : 요소 이름은 P
  • – : 시작 태그는 필수적
  • O : 종료 태그는 선택적
  • (%inline;) : 자식 요소로써 인라인 콘텐츠만 허용
  • * : 자식 요소는 생략하거나 한 번 이상 사용 할 수 있음
  • — paragraph — : 문단임


요소 이름 다음에 등장하는 기호 하이픈(-) 또는 알파벳(O)는 시작 태그 또는 종료 태그가 필수적인지 선택적인지를 기술하는데 하이픈(-)은 태그의 선언이 필수적임을 의미하며 알파벳(O)는 선택적으로 생략할 수도 있다(can be Omitted)는 것을 의미 합니다. 

만약 시작과 종료 태그가 모두 필수적이라면 ‘P – -‘ 이라고 표기 될 것이며 모두 필수적이지 않다면 ‘P O O’ 라고 표기 했을 것입니다.


시작 태그와 종료 태그 다음에 등장하는 ‘자식 명세’는 자식 요소로써 무엇을 허용할 것인지에 대한 내용이 선언됩니다. 

예를 들어 HTML/XHTML 호환모드에서 <address> 요소는 기본적으로 인라인 요소만을 허용하나  예외적으로 <p> 요소도 허용하고 있는데 DTD 명세는 이것을 어떻게 설명하는지 확인해 보겠습니다.

<!ELEMENT ADDRESS – – ((%inline;)|P)*  — information on author –>

<address> 요소는 시작과 종료 태그가 모두 필수적이고 인라인(%inline;)요소 또는(|) 문단 요소 <p>를 사용할 수 있다. 

자식 요소들은 모두 생략이 가능하고 한 번 이상 사용할 수 있다.


<img> 요소와 같이 자식 요소를 포함하지 않는 요소들은 어떻게 선언할까요? 

‘자식 명세’를 정의하는 곳에 EMPTY 라고 적혀 있는 경우 자식 요소를 가질 수 없다는 의미 입니다.

<!ELEMENT IMG – O EMPTY — Embedded image –>

<img> 요소는 시작태그는 필수적이지만 종료태그는 생략 가능한데 자식 요소는 비어(EMPTY)있다.


속성 명세 읽기

속성에 관한 명세는 항상 관련 요소에 대한 명세 다음에 등장하지만 어떤 요소에 대한 설명인지 보다 명확히 하기 위하여 명세 안쪽에 명시적으로 관련 요소 이름을 지명 하고 있습니다. 

속성의 명세는 다음과 같은 구조를 갖습니다.

<!ATTLIST  관련 요소 이름을 지명   속성 이름  속성의 값  속성의 기본 값 또는 필수적인지 아닌지  — 설명 —>

좀더 구체적으로 이해하기 위하여 <input> 요소에 대한 속성 명세를 예제로 옮겨 왔습니다. 

일단 어떤 모양인지 눈여겨 봐 주세요. 이해하기 쉽게 몇 가지 속성만 추렸고 각각을 분리해서 설명드리겠습니다.


<!ATTLIST INPUT 

%attrs;    — %coreattrs, %i18n, %events — 

type    %InputType;    TEXT    — 타입 — 

name    CDATA    #IMPLIED    — 서버측에 넘겨주는 이름 —

>

어떤 요소의 속성에 관한 명세인지 지명하는 부분은 다음과 같이 명세의 첫 번째 줄에 등장 합니다. 

<input> 요소에 관한 속성 목록을 나열하겠다는 의미로 해석하면 됩니다.


<!ATTLIST INPUT

다음 구문은 온통 퍼센트 %기호로 시작하여 세미콜론; 으로 끝나는 ‘변수’로만 작성되어 있습니다. 

이런 경우에는 변수가 무엇을 의미하는지 해석해야 합니다. 

%attrs; 라는 변수에는 다른 HTML 요소에서도 공통으로 사용되는 전역 속성들의 목록(예를 들면 id, class, style, title과 같은)이 포함되어 있습니다. 그런데 — 주석 — 안쪽에는 %attrs;라는 변수가 또 다른 변수들의 집합이라는 것을 설명하고 있네요.


%attrs;    — %coreattrs, %i18n, %events —

%coreattrs; 라는 변수는 모든 HTML 요소들의 핵심(core) 속성에 해당하는 id, class, style, title 속성을 하나의 변수로 만든것 입니다.

%i18n; 이라는 변수는 국제화 속성으로써 lang, dir 속성을 하나의 변수로 만들었습니다. 

%i18n; 이라는 변수 이름은 본래 %internationalization;(%국제화;)이라는 용어가 너무 길어서 알파벳 첫 글자 ‘i’와 마지막 글자 ‘n’ 사이에 있는 18개의 알파벳을 모두 표기하지 않고 숫자로 바꿔 표기한 것입니다. 


국제화 속성의 하나인 lang 속성은 콘텐츠의 자연어가 어떤 언어인지(예를 들면 영어인지 한국어인지) 지정하는 속성이고 dir 이라는 속성은 문자의 방향(direction)에 관한 속성 입니다. 

대부분의 언어가 왼쪽에서 오른쪽으로(Left To Right) 읽고 쓰기 때문에 기본값은 dir="ltr" 이고 모든 요소에서 생략되어 있습니다. 

만약 아랍어라면 dir="rtl" (Right To Left) 으로 지정하여 기본 ‘ltr’ 으로 설정된 방향 속성을 ‘rtl’ 으로 덮어쓰기 해야 할 것입니다.


%events; 라는 변수는 자바스크립트 이벤트 핸들러들의 집합으로써 다음과 같습니다. 

  • onclick     — 버튼을 누른 후 뗌 —
  • ondblclick     — 버튼을 연달아 두 번 클릭 —
  • onmousedown     — 버튼 누름 —
  • onmouseup     — 버튼 뗌 —
  • onmouseover     — 마우스 포인터가 위에 있는 —
  • onmousemove     — 마우스 포인터가 움직임 —
  • onmouseout     — 마우스 포인터가 벗어남 —
  • onkeypress     — 키를 누른 후 뗌 —
  • onkeydown     — 키를 누름 —
  • onkeyup     — 키를 뗌 —



다음은 type 이라는 속성에 관한 명세 부분 입니다.

‘속성 이름, 속성의 값, 속성의 기본 값’ 순으로 명시되어 있습니다. 

속성이 ‘필수적인지 아닌지’의 여부는 표시되지 않았는데 왜냐하면 ‘속성의 기본 값’이 표기되어 있기 때문입니다. 

속성에 기본 값이 있다는 것은 속성을 생략할 수 있다는 의미로 해석이 가능하기 때문에 #IMPLIED라는 설명은 생략되었습니다.


type    %InputType;    TEXT    — 타입 —

사람이 이해할 수 있는 말로 type 속성에 관한 명세를 풀어보면 다음과 같이 해석할 수 있습니다.

<input> 요소에는 말이지 type 이라는 속성이 있어 type 이라는 속성은 %InputType; 이라는 값을 가질 수 있는데

%InputType;은 TEXT | PASSWORD | CHECKBOX | RADIO | SUBMIT | RESET |    FILE | HIDDEN | IMAGE | BUTTON 이런 값들을 가질 수 있지

그리고 이 많은 값 가운데 기본값은 TEXT 란다

type="text" 이것이 <input> 요소의 기본 값이라는 거지

속성에 대한 기본 값이 있기 때문에 이 속성은 생략(#IMPLIED)할 수도 있단다



다음은 name 속성에 관한 명세 입니다.

name    CDATA    #IMPLIED    — 서버측에 넘겨주는 이름 —

name 속성은 값으로써 CDATA(브라우저가 해석하거나 변조하지 않고 전달이 가능한 순수한 문자들)만 올 수 있는데 이 속성은 생략할 수 있다는 의미 입니다.



Jaehee's WebClub