본문 바로가기
정보과학/웹서비스특론

XML 스키마 (2)

by J1소프트 2023. 9. 6.
728x90

1. XML 스키마 데이터 타입

 

1.1 데이터 타입

엘리먼트의 내용(컨텐츠) 또는 속성값으로 어떤 종류의 정보가 어떤 형태로 작성될 것인지를 결정하는 것이 데이터 타입이다. DTD 에서는 엘리먼트의 내용이 단순한 데이터일 경우 #PCDATA 만 지원 가능했고, 속성값으로는 CDATA 타입만 가능했다. 하지만 스키마 언어에서는 다양한 데이터 타입을 지원함으로써 XML 문서 구조를 더욱 정밀하게 정의할 수 있게 되었다. DTD 에서는 사용자가 임의로 데이터 타입을 정의해서 사용할 수 없었지만 스키마 언어는 사용자가 임의로 데이터 타입을 정의해서 엘리먼트 선언이나 속성 선언에 사용할 수 있다.

예를 들어, 13 자리의 주민등록번호 데이터 타입을 만들 수도 있고, 범위를 가지는 숫자형의 데이터 타입을 만들 수도 있다. ‘-’를 포함하는 전화번호와 같이 특정 형태를 가지고 있는 데이터 타입도 스키마 언어로 만들 수 있다.

 

1.2 데이터 타입의 분류

XML 스키마의 데이터 타입은 아래와 같이 미리 정의한 빌트인(Built-in) 타입과 사용자 정의 데이터 타입(user-derived datatype)으로 분류할 수 있다.

그림 1. XML 스키마 데이터 타입

빌트인 데이터 타입은 XML 스키마 표준에서 정의한 데이터 타입이다. 빌트인을 우리말로 번역하면 내장된이라는 뜻으로 별도의 정의 없이 사용 가능한 것이라고 이해하면 된다.

스키마 언어에서는 스키마 문서 작성자의 편리성을 위해서 다양한 단순 타입을 미리 정의하고 있기 때문에 별도의 정의 없이 해당 데이터 타입이 사용 가능하다. 보통 “xsd” 네임스페이스 접두사를 붙여 사용하는데, 엘리먼트의 데이터 값의 종류 및 속성 값의 종류를 지정할 때 사용되며, 또한 사용자 정의 단순 타입의 기저형(base datatype)으로 사용된다. 예를 들면,

<xsd:string> 혹은 <xsd:integer>와 같은 요소에서는 미리 정의한 빌트인 데이터 타입을 사용하고 있다. 빌트인 데이터 타입은 단순 데이터 타입으로 분류할 수 있고, 이것은 다시 기본 데이터 타입과 파생 데이터 타입으로 분류할 수 있다. 개발자가 단순 타입을 정의하기 위해서는 <simpleType> 요소를 이용하고, 복합 데이터 타입을 정의하기 위해서는 <complexType>요소를 이용한다.

빌트인 데이터 타입 중 단순 데이터 타입은 빌트인 단순 데이터 타입으로는 부족하고 표현하기 어려운 데이터 타입을 사용자가 직접 정의해서 사용하는 데이터 타입을 말한다.

이것은 빌트인 단순 타입과는 달리 “xsd” 접두사를 붙이면 안 된다. 사용 용도는 빌트인 단순 타입과 마찬가지로 엘리먼트의 데이터 값의 종류 및 속성 값의 종류를 지정할 때 사용된다.

복합 데이터 타입의 용도는 속성을 가지는 엘리먼트 선언일 경우와 자식 엘리먼트를 가지는 엘리먼트 선언일 경우에 사용된다. 물론 속성과 자식 엘리먼트를 동시에 가지는 엘리먼트 선언일 경우에도 사용된다. 복합 타입은 사용자가 정의해서 사용하는 사용자 정의 복합 타입만 존재한다.

 

참조 사이트
[XML Schema Part 2: Datatype3 Built-in datatypes]
                 http://www.w3.org/TR/xmlschema-2/#built-in-datatypes

2. 단순형

XML 스키마의 자료형에는 내용이 텍스트뿐인 단순형과 자식요소나 속성을 가질 수 있는 복합형이 있다.

단순형은 simpleType 으로 선언한다. 원래의 자료형에 대해서 제약을 추가한 형태로 새로운 자료형을 생성한다. 이때 원래의 자료형을 기저형(base type), 추가된 제약을 제약 패싯(constraining facet)이라고 한다. 제약에는 제한(restriction), 리스트(list), 공용(union)의 3 종류가 있다.

 

2.1 제한

제한은 restriction 으로 선언한다. 어떤 식으로 제한을 부여할 수 있을까는 원래 자료형(기저형)의 종류에 따라 달라진다.

참고사이트
[기저형] 여기서는 수치와 문자열로 구분되어 있지만 실제는 좀 더 세부적으로 규정되어 있다.
[XML Schema Part 0: Primer-B Simple Types & their Facets]
                         http://www.w3.org/TR/xmlschema-0/#SimpleTypeFacets

2.1.1 수치형의 제한

기저형이 수치인 경우에는 최대값, 최소값, 자리수를 지정할 수 있다.

*[] 수치형의 제한

<xsd:simpleType name="resultType">
   <xsd:restriction base="xsd:integer">
       <xsd:minInclusive value="0" />
       <xsd:maxInclusive value="100" />
   </xsd:restriction>
</xsd:simpleType> 

 

수치형에 사용되는 제약들로서는 다음과 같은 것들이 있으며, 이밖에 수치형에 대해서도 pattern, enumeration, whiteSpace 를 사용할 수 있다.

totalDigits 총 자리수
fractionDigits 소수점 이하의 자리수
maxInclusive 최대값 (지정한 값을 포함)
maxExclusive 최대값 (지정한 값을 포함하지 않음)
minInclusive 최소값 (지정한 값을 포함)
minExclusive 최소값 (지정한 값을 포함하지 않음)

 

2.1.2 문자열의 제한

문자열형의 경우에 문자의 길이를 지정할 수 있다. 이외에도 값의 후보를 지정하는 열거형(enumeration)과 패턴(pattern)에 의한 지정도 가능하다.

 

* [] 문자열형의 제한

<xsd:simpleType name="isbnType">
   <xsd:restriction base="xsd:string">
       <xsd:length value="10" />
   </xsd:restriction>
</xsd:simpleType> 

문자열에 적용되는 제약의 종류에는 다음과 같은 것들이 있다.

length 문자의 길이 (고정길이)
minLength 문자 길이의 최소값
maxLength 문자 길이의 최대값
pattern 패턴 표현
enumeration 열거
whiteSpace 공백문자의 처리
preserve 상태를 그대로 유지
replace TAB, CR, LF 를 스페이스(#x20)로 바꾼다
collapse 연속된 공백문자를 하나의 스페이스로 교환하고, 처음 또는
마지막의 공백문자는 제거
 

2.2 열거

후보가 되는 값들이 이미 결정되어 있는 경우에는 enumeration 으로 열거한다.

 

* 열거의 예

<xsd:simpleType name="bookStatusType">
     <xsd:restriction base="xsd:string">
         <xsd:enumeration value="read"/>
         <xsd:enumeration value="purchase"/>
         <xsd:enumeration value="wish"/>
     </xsd:restriction>
</xsd:simpleType> 

 

2.3 패턴

정규표현에 의한 제한은 pattern 으로 지정한다.

참고 사이트
[XML Schema Part 2: Datatypes - F Regular Expressions]
          http://www.w3.org/TR/xmlschema-2/#regexsd

* 패턴 표현의 예

<xsd:simpleType name="dateType">
     <xsd:restriction base="xsd:string">
           <xsd:pattern value="(1[0-2]|[0]?[0-9])월([3][01]|[0-2]?[0-9])일" />
     </xsd:restriction>
</xsd:simpleType> 

 

2.4 리스트

<postion>10 20</position>이나 <mark postion="10 20" />과 같이 여러 개의 값을 취하는 자료형은 list 로 정의한다. 리스트라는 것은 공백문자로 구별되는 값으로서, DTD 의 NMTOKENS, IDREFS, ENTITIES 에 해당한다.

리스트의 값을 제한하고 싶은 경우에는 다음과 같이 파생 자료형을 만들고 length 에 의한 제한을 추가한다.

* 리스트의 예

<xsd:simpleType name="positionType">
     <xsd:list itemType="xsd:positiveInteger" />
</xsd:simpleType>
<xsd:simpleType name="xyPositionType">
      <xsd:restriction base="positionType">
            <xsd:length value="2" />
      </xsd:restriction>
</xsd:simpleType> 

2.5 공용

<point>95</point>이나 <point>불분명</point>와 같이 취할 수 있는 값의 종류가 여러 가지인 경우에는 union 으로 정의한다.

 

* 공용의 예

<xsd:simpleType name="pointType">
      <xsd:union memberTypes="xsd:integer xsd:string" />
</xsd:simpleType> 

union 요소 내에서 각각의 자료형에 대해서 제한을 가하는 것도 가능하다.

* 공용 내에서 제한을 부여하는 경우

<xsd:simpleType name="pointType">
     <xsd:union>
         <xsd:simpleType>
             <xsd:restriction base="xsd:integer">
                 <xsd:minInclusive value="0" />
                 <xsd:maxInclusive value="100" />
             </xsd:restriction>
         </xsd:simpleType>
         <xsd:simpleType>
             <xsd:restriction base="xsd:string">
                  <xsd:enumeration value="불분명" />
             </xsd:restriction>
         </xsd:simpleType>
     </xsd:union>
</xsd:simpleType> 

3. 복합형

내용이 텍스트 이외, 즉 자식요소가 있는 경우나 빈 요소의 경우 또는 속성이 있는 경우에는 복합형으로서 정의한다.

복합형은 complexType 으로 선언한다. 내용이 문자 데이터인 경우에는 simpleText, 자식 요소의 경우에는 sequence 또는 choice 로 정의한다. 문자 데이터와 자식요소가 혼합된 경우에는 complexType mixed=“true”를 지정한다.

 

* 자료형 정의 형식

<xsd:complexType name="자료형의 이름" mixed="true">
     1. 자식 요소가 있는 경우
         <xsd:sequence> ~ </xsd:sequence> 또는 <xsd:choice> ~ </xsd:choice>
     2. 문자 데이터만 있는 경우
           <xsd:simpleText> ~ </xsd:simpleText>
     3. 속성이 있는 경우
         <xsd:attribute> ~ </xsd:attribute> 또는 <xsd:attributeGroup> ~ </xsd:attributeGroup>
</xsd:complexType>
 

3.1 자식 요소

자식 요소가 있는 경우에는 sequence(또는 choice)element 를 조합해서 선언한다. 자식 요소가 순서 있게 나타나는 경우에는 sequence, 어떤 1 개만 나타나는 경우에는 choice 사용한다. sequence choice 는 각각 DTD , | 에 해당한다. 또한 sequence 와 choice 는 내포(nest)해서 표현하는 것이 가능하다. sequence 요소 안에 다시 sequence 요소를 사용하거나 choice 요소를 사용하는 것이 가능하다. element name=으로 요소명을 정의하거나 혹은 ref=로 별도의 정의를 참조한다.

 

* 자식 요소 지정의 예

* diaryType 형의 자식요소로서 date 와 event 가 1 회씩 순차적으로 나타나는 경우
<xsd:complexType name="diaryType">
     <xsd:sequence>
         <xsd:element ref="date" />
         <xsd:element ref="event" />
     </xsd:sequence>
</xsd:complexType>

* eventType 형의 자식요소로서 book 과 cd 가 중 어떤 것이든 1 회 나타나는 경우
<xsd:complexType name="eventType">
     <xsd:choice>
         <xsd:element ref="cd" />
         <xsd:element ref="book" />
     </xsd:choice>
</xsd:complexType>

출현 순서에 관계없는 경우는 sequence 대신에 all 을 사용한다. 출현 회수는 기본적으로 1 회이지만, minOccurs="0"으로 0 회로 변경할 수 있다. 또한, 출현 순서도 회수도 관계없는 경우에는 choice 를 사용한다.

 

3.2 자식 요소의 출현 회수

자식 요소의 출현 회수는 minOccurs= maxOccurs=로 각각 정의할 수 있다. 지정하지 않는 경우는 둘 다 1 의 값을 가지며 따라서 출현회수는 1 회가 된다.

 

* 출현 회수 지정의 예

<xsd:complexType name="diaryType">
     <xsd:sequence>
         <xsd:element ref="title" minOccurs="0" />
         <xsd:element ref="date" />
         <xsd:element ref="event" maxOccurs="unbounded" />
         <xsd:element ref="memo" minOccurs="0" maxOccurs="unbounded" />
     </xsd:sequence>
</xsd:complexType> 
 

3.3 자식 요소의 그룹화

group 을 사용해서 자식 요소를 그룹화할 수 있다. 예를 들어, “cd 요소와 book 요소의 어느 것이든이라는 정의를 그룹화하기 위해서는 다음과 같이 한다.

 

* 자식 요소의 그룹화의 예

<xsd:group name="topicGroup">
     <xsd:choice>
         <xsd:element ref="cd" />
         <xsd:element ref="book" />
     </xsd:choice>
</xsd:group>

또한, 그룹을 참조하는 경우에도 group 를 사용한다.

 

* 그룹의 참조

* eventType 형은 혼합된 경우로, 자식요소로는 topicGroup 그룹, 속성으로는 event.attlist 그룹을 가지는 경우
<xsd:complexType name="eventType" mixed="true">
     <xsd:group ref="topicGroup" maxOccurs="unbounded" />
     <xsd:attributeGroup ref="event.attlist" />
</xsd:complexType> 
 

3.4 자식 요소와 문자 데이터의 혼합

요소의 내용에 자식 요소와 문자 데이터 모두가 존재하는 경우에는 complexType 에 mixed="true"를 지정한다. 예를 들어, eventType 형을 혼합 내용으로 정의하면 다음과 같이 할 수 있다.

 

* 자식 요소와 문자 데이터가 혼합된 경우

<xsd:complexType name="eventType" mixed="true">
     <xsd:choice minOccurs="0" maxOccurs="unbounded">
         <xsd:element ref="cd" />
         <xsd:element ref="book" />
     </xsd:choice>
</xsd:complexType> 

 

3.5 속성

요소에 속성이 있는 경우에는 attribute 또는 attributeGroup 으로 선언한다. 예를 들어eventType 형에 category 속성이 존재하는 경우에는 다음과 같이 한다.

 

* 속성 지정의 예

<xsd:complexType name="eventType" mixed="true">
     <xsd:choice minOccurs="0" maxOccurs="unbounded">
         <xsd:element ref="cd" />
         <xsd:element ref="book" />
     </xsd:choice>
     <xsd:attribute name="category" type="xsd:string" />
</xsd:complexType> 
 한편, 속성 그룹을 참조하는 경우에는 다음과 같이 한다.

* 속성 그룹의 예

<xsd:complexType name="eventType" mixed="true">
     <xsd:choice minOccurs="0" maxOccurs="unbounded">
           <xsd:element ref="cd" />
           <xsd:element ref="book" />
     </xsd:choice>
     <xsd:attributeGroup ref="event.attlist" />
</xsd:complexType>
<xsd:attributeGroup name="event.attlist" >
     <xsd:attribute name="category" type="xsd:string" />
</xsd:attributeGroup> 
 

3.6 문자 데이터

내용에 자식 요소가 없는 경우에는 simpleContent 로 선언하며, 내용의 유형은 extention 으로 표현한다.

 

* 문자 데이터만 있는 지정의 예

<xsd:complexType name="dateType">
     <xsd:simpleContent>
         <xsd:extension base="xsd:date" />
     </xsd:simpleContent>
</xsd:complexType>

* 속성이 있는 경우
<xsd:complexType name="dateWithWeatherType">
     <xsd:simpleContent>
         <xsd:extension base="xsd:date">
             <xsd:attribute name="weather" type="xsd:string" use="optional" />
         </xsd:extension>
     </xsd:simpleContent>
</xsd:complexType> 
 

 

3.7 빈 요소

자식 요소나 텍스트를 정의하지 않는 경우는 빈 요소가 된다. 속성이 있는 경우는 complexType 안에 attribute 또는 attributeGroup 을 적는다.

* 빈 요소 지정의 예

<xsd:complexType name="photoType">
      <xsd:attribute name="url" type="xsd:anyURI" use="required" />
</xsd:complexType> 
 

3.8 제한 없음

자식 요소의 제한을 없애고 싶은 경우에는 any, 속성의 제한을 없애고 싶은 경우에는 anyAttribute 를 사용한다. 제한 없는 자료형에는 이밖에 anyType 형이 있지만, any 및 anyAttribute 의 경우는 (1) 네임스페이스를 지정할 수 있고 (2) 검증을 스킵할 수 있는 특징이 있다.

검증을 할 것인가 말것인가는 processContents=로 지정한다.

processContents="skip"으로 검증을 하지 않고 “lax”라면 정의가 있을 때만 검증한다. 또한 “strict”는 항상 검증하라는 의미로서, 무지정한 경우에는 기본값이 “strict”로서 취급한다.

 
 * 제한 없음의 예
<xsd:complexType name="memoType">
     <xsd:sequence minOccurs="0">
          <xsd:any processContents="skip" />
     </xsd:sequence>
     <xsd:anyAttribute processContents="skip" />
</xsd:complexType> 

4. 네임스페이스

DTD 에는 없는 XML 스키마의 특징 중의 하나가 바로 네임스페이스이다. 정의한 스키마와 네임스페이스를 결부시키기 위해서는 targetNamespace=를 사용한다. 이밖에 외부 스키마 파일의 임포트(import)any anyAttribute 를 사용하는 경우에도 네임스페이스를 지정할 수 있다. 

4.1 대상 네임스페이스의 지정 (targetNamespace)

schema targetNamespace=로 스키마에 속하는 네임스페이스를 지정할 수 있다. 예를 들어, diary.xsd 로 정의된 스키마와 http://example.com/xsd/diary라는 네임스페이스를 결부시킬 때에는 다음과 같이 한다.

* 네임스페이스의 결합
<xsd:schema targetNamespace="http://example.com/xsd/diary"
                                  xmlns:xsd="http://www.w3.org/2001/XMLSchema
                                         xmlns="http://example.com/xsd/diary">
     <xsd:element name="diary">
         <xsd:complexType>
             <xsd:sequence>
                 <xsd:element ref="date" />
                 <xsd:element ref="event" maxOccurs="unbounded" />
             </xsd:sequence>
         </xsd:complexType>
     </xsd:element>
...
</xsd:schema> 

 

대상 네임스페이스가 지정된 스키마를 사용하는 경우

targetNamespace=가 지정되어 있는 스키마는 그 네임스페이스만 유효하다. 예를 들어스키마 파일 diary.xsd 를 사용하는 XML 파일은 네임스페이스로서 http://example.com/xsd/diary"를 지정할 필요가 있으며 다음과 같이 한다.

 

* diary.xsd 를 사용하는 XML 파일의 예

<diary xmlns="http://example.com/xsd/diary"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation=" http://example.com/xsd/diary
        http://.../diary.xsd">
     <date weather="맑음“>02 월 28 일</date>
<event>
...
</event>
</diary> 
 

4.2 네임스페이스 접두사의 사용

스키마 정의에서 네임스페이스 접두사를 사용할 수 있다. 이 경우 (1)name=으로 부여된 이름에는 접두사를 붙이지 않고, (2)스키마 정의를 참조할 때에는 접두사를 붙인다는 점에 주의하기 바란다.

예를 들어, diary.xsd 의 네임스페이스 http://example.com/xsd/diary"d라는 네임스페이스 접두사를 붙이는 경우 다음과 같이 한다.

 

* 네임스페이스 접두사를 사용한 예

<xsd:schema targetNamespace="http://example.com/xsd/diary"
                                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                                       xmlns:d="http://example.com/xsd/diary">
     <xsd:element name="diary"> 
         <xsd:complexType>
             <xsd:sequence>
                 <xsd:element ref="d:date" />
                 <xsd:element ref="d:event" maxOccurs="unbounded" />
                 <xsd:element ref="d:htmlExample" minOccurs="0" maxOccurs="unbounded" />
             </xsd:sequence>
         </xsd:complexType>
     </xsd:element>
     <xsd:simpleType name="dateType">
         <xsd:restriction base="xsd:string">
             <xsd:pattern value="(1[0-2]|[0]?[0-9])월([3][01]|[0-2]?[0-9])일" />
         </xsd:restriction>
     </xsd:simpleType>
     <xsd:element name="date">
         <xsd:complexType>
             <xsd:simpleContent>
                 <xsd:extension base="d:dateType">
                     <xsd:attribute name="weather" use="required">
                         <xsd:simpleType>
                             <xsd:restriction base="xsd:string">
                                 <xsd:enumeration value="맑음" />
                                 <xsd:enumeration value="흐림" />
                                 <xsd:enumeration value="비" />
                             </xsd:restriction>
                         </xsd:simpleType>
                     </xsd:attribute>
                </xsd:extension>
             </xsd:simpleContent>
         </xsd:complexType>
     </xsd:element>
     <xsd:element name="event">
         <xsd:complexType mixed="true">
             <xsd:choice maxOccurs="unbounded">
                 <xsd:element ref="d:cd" />
                 <xsd:element ref="d:book" />
             </xsd:choice>
         <xsd:attribute name="category" type="xsd:string" />
     </xsd:complexType>
</xsd:element>
<xsd:element name="cd"> 
...
</xsd:element>
<xsd:element name="book">
...
</xsd:element>
</xsd:schema>

XML 파일 측면에서는 네임스페이스 URI 만 스키마 정의와 같게 한다면 네임스페이스 접두사는 무엇을 사용해도 상관없다. 따라서 위의 diary.xsd 와 앞에서 살펴본 예(4.1 절의 diary.xsd 를 사용한 XML 파일의 예)XML 데이터는 그대로 조합해서 사용할 수 있다.


5. 유일 제약 정의

 

5.1 유일 제약이란?

유일 제약이란 중복된 값을 가지지 않도록 제한하는 것을 말한다. 예를 들어 주민등록번호는 그 사람만이 가지고 있는 유일한 속성이다. 만약 주민등록번호가 같은 사람이 많다면 어떻게 되겠는가? 분명히 문제가 생길 것이다. 그래서 주민등록번호와 같은 유일한 값을 가지는 곳에 유일 제약을 걸어두면 중복된 데이터가 입력되는 것을 방지할 수 있다.

 

XML 에서는 DTD 내에서 ID 속성 타입으로 유일 제약을 만들 수 있다. 그리고 스키마에서는 ID 속성 타입뿐만 아니라 <key> <unique> 엘리먼트를 사용해서 유일 제약을 정의할 수 있다. 이렇게 정의된 속성값은 파서에 의해서 중복된 데이터가 입력되었는지 검증이 이루어지고, 중복된 값이 발견되면 유효하지 않은 문서로 취급된다. ID 속성 타입으로 지정된

속성은 IDREF 속성 타입으로 지정된 속성에서 참조 가능하다. 그리고 <key> 엘리먼트로 지정된 속성은 <keyref> 엘리먼트로 지정된 속성에서 참조 가능하다.

 

이것은 관계형 데이터베이스에서 사용하는 유일 제약과 아주 비슷하다. 관계형 데이터베이스에서는 기본 키 및 유일 제약(unique)을 이용하여 유일 제약을 적용한다. 기본 키 및 유일 제약이 설정된 컬럼은 중복된 데이터가 입력되지 않도록 데이터베이스 관리 시스템(DBMS) 차원에서 관리된다. 이렇게 기본 키로 컬럼이 지정되면, 참조 키(Foreign Key)가 설정된 컬럼에서 참조가 가능해진다.

 

5.2 ID 속성 타입을 이용한 구현

ID 속성 타입은 빌트인 단순 타입으로 별도의 정의 없이 사용될 수 있다. ID 속성 타입을 사용하면 XML 문서 전체에서 유일한 값을 가지도록 속성을 만들 수 있다. 다음은 <book> 엘리먼트의 id 속성 및 <kind> 엘리먼트의 id 속성값이 유일한 값을 가지도록 ID 속성 타입을 적용해서 유일 제약을 구현한 예제이다.

 

* XML 스키마 문서

<!-- ID 타입 지정 -->
<xsd:attribute name="id" type="xsd:ID" use="required"/>

* XML 문서

<kind id="k1">컴퓨터</kind>
<kind id="k2">소설</kind>
<kind id="k3">잡지</kind>
<book id="b1">XML 기초서</book>
<book id="b2">Java And XML</book> 

XML 문서 작성 시 주의해야 될 점은 ID 타입의 값은 숫자로 시작하면 안 되며, 중간에 공백이 있어서도 안 된다.

 

5.3 key 엘리먼트를 이용한 구현

<key> 엘리먼트로 유일 제약을 정의하는 것은 관계형 데이터베이스에서 기본 키를 설정하는 것과 비슷하다. 기본 키를 설정하려면 먼저 대상이 되는 테이블을 결정하고 실제 기본 키가 적용될 컬럼을 지정하면 된다. 스키마에서는 유일 제약이 적용될 대상 엘리먼트를 먼저 결정하고 그 다음 실제로 유일 제약이 적용될 부분을 언급해야 된다. 이 때 유일 제약이 적용될

부분은 보통 대상 엘리먼트의 속성명이 온다. 다음은 <key> 엘리먼트 사용 문법이다.

 

* 문법

<key name="키 이름">
    <selector xpath="대상 엘리먼트의 xpath 경로"/>
    <field xpath="적용할 속성 이름:/>
</key> 

<key> 엘리먼트의 name 속성은 필수 속성이므로 생략하면 안 된다. 키 이름은 <keyref> 엘리먼트에서 참조할 경우 사용된다. <selector> 엘리먼트의 xpath 속성값으로는 대상이 되는 엘리먼트의 문서 내 경로를 xpath 표현식으로 나타내면 된다. 보통 key 정의는 루트 엘리먼트 선언 내에서 만들어지므로 xpath 속성값으로 루트 엘리먼트에서부터 상대 경로로 표현하면 된다.

 

* 문법

<selector xpath="자식 엘리먼트/자손 엘리먼트/.../대상 엘리먼트">
또는
<selector xpath="./자식 엘리먼트/자손 엘리먼트/.../대상 엘리먼트">

* 스키마 문서

<selector xpath="kinds/kind">
<selector xpath="./kinds/kind">
<selector xpath="book"/>
<selector xpath="./book"/> 

<field> 엘리먼트의 xpath 속성값으로는 유일 제약이 적용될 속성을 지정해 주면 된다.

속성을 뜻한다고 해서 ‘@’ 기호를 속성명 앞에 붙여 줘야 한다.

 

* 문법

<field xpath="@대상 엘리먼트의 속성명"/>
또는
<field xpath="./@대상 엘리먼트의 속성명"/>
 * 스키마 문서
<field xpath="@id"/>
<field xpath="./@kind"/>

<key> 엘리먼트로 지정된 유일 제약이 적용되는 값은 <keyref> 엘리먼트로 지정된 부분에서 참조 가능하다. 마치 관계형 데이터베이스의 기본 키로 지정된 컬럼의 값을 참조 키로 지정된 컬럼에서 참조하는 것과 같은 원리이다.

IDREF 속성 타입과 다른 점은 <keyref> 엘리먼트에 의해 속성이 지정되면 참조하는 해당 key 속성값만 올 수 있고, 다른 key 속성값은 올 수 없다는 것이다. 다음은 <keyref> 엘리먼트의 사용 문법이다.

 

* 문법

<keyref name="키 참조 이름" refer="참조할 키 이름">
     <selector xpath="대상 엘리먼트의 xpath 경로"/>
     <field xpath="적용할 속성 이름"/>
</keyref> 

<keyref> 엘리먼트의 name 속성 및 refer 속성은 필수 속성이므로 생략하면 안 된다.

<selector> 엘리먼트와 <field> 엘리먼트의 문법은 <key> 엘리먼트의 자식 엘리먼트로 오는 <selector> 엘리먼트와 <field> 엘리먼트 문법과 같기 때문에 생략한다.

 

5.4 unique 엘리먼트를 이용한 구현

속성값이나 엘리먼트 컨텐츠 데이터 값의 유일성을 보장할 필요성만 있고, 그 값을 참조할 필요가 없을 경우에는 해당 부분에 대해 key 를 정의할 필요가 없고, 유일성만 보장하도록 <unique> 엘리먼트를 사용해 유일 제약을 적용할 수 있다. 이것은 관계형 데이터베이스에서 데이터의 중복만 방지하면서, 참조 키에서 참조되지 않는 유일제약(unique)을 만드는 것과

동일한 의미이다. 다음은 <unique> 엘리먼트의 사용 문법이다.

 

* 문법

<unique name="유일 제약 이름">
     <selector xpath="대상 엘리먼트의 xpath 경로"/>
     <field xpath="적용할 속성 이름"/>
</unique> 

<unique> 엘리먼트의 name 속성은 필수 속성이므로 생략하면 안 된다. 그리고 <selector>, <field> 엘리먼트 사용 방법은 <key> 엘리먼트의 경우와 동일하다.

 

다음은 <book> 엘리먼트의 id 속성을 <unique> 엘리먼트를 이용해서 유일 제약을 적용한 예이다. id 속성값에 중복된 값이 오면 안 된다.

 

* 스키마 문서

<xsd:unique name="uniqueBook">
     <xsd:selector xpath="book"/>
     <xsd:field xpath="@id"/>
</xsd:unique>

6. 노테이션 선언

6.1 노테이션이란?

노테이션(notation)은 그림 파일이나 동영상 파일, 음악 파일의 포맷을 식별하기 위해서 사용되는 특별한 엘리먼트이다. 노테이션은 MIME 타입과 유사한 기능을 한다고 보면 된다.

XML 파서가 해석할 수 없는 비 문자 데이터가 어떤 종류의 포맷을 가지고 있고, 이 데이터를 처리할 수 있는 헬퍼(helper) 프로그램은 어떤 것인지를 응용프로그램에게 알려줌으로써 응용프로그램이 비 문자 데이터를 어떻게 처리할지를 결정할 수 있도록 해 주는 것이다.

 

6.2 노테이션 선언 문법

* 문법

<notation
     name="노테이션 이름"
     public="공개 식별자(보통 MIME 타입을 지정)"
     system="헬퍼 프로그램"/> 

public 속성에는 보통 MIME 타입이 기술되고, system 속성에는 비 문자 데이터를 처리해 주는 헬퍼 프로그램에 대한 정보가 기술된다. 선언된 노테이션을 속성값 또는 데이터 값으로 사용할 때 반드시 빌트인 단순 타입인 NOTATION 을 제한하는 사용자 정의 단순 타입을 만들어서 사용해야 된다.

* 스키마 문서

<!-- NOTATION 선언 -->
<xsd:notation name="bmp" public="image/bmp" system="mspaint.exe"/>
<xsd:notation name="gif" public="image/gif" system="photoshop.exe"/>
<xsd:notation name="jpeg" public="image/jpeg" system="photoshop.exe"/>

<!-- 글로벌 단순 타입의 정의 -->
<xsd:simpleType name="stType">
    <xsd:restriction base="xsd:NOTATION">
        <xsd:enumeration value="bmp"/>
        <xsd:enumeration value="gif"/>
        <xsd:enumeration value="jpeg"/>
    </xsd:restriction>
</xsd:simpleType> 

<!-- 글로벌 타입의 적용 -->
<xsd:attribute name="type" type="stType"/>

사용자 정의 단순 타입인 stType 은 열거형으로 노테이션을 사용할 수 있도록 정의한 것이다.

이 단순 타입을 type 속성 선언 시 데이터 타입으로 지정함으로써 type 속성의 값으로 bmp, gif, jpeg 노테이션 중 한 개의 값만 사용할 수 있도록 한 것이다.


7. 스키마 문서의 결합

7.1 스키마 문서의 결합이란?

그림 2. 스키마 문서의 결합 및 사용

유지 관리의 목적으로 스키마 문서는 한 개만 작성되는 것이 아니라 여러 개의 스키마 문서로 작성될 수 있다. 공통적으로 사용되는 정의 및 선언들을 별도의 스키마 문서에서 작성하고, 스키마 문서에서는 같은 내용이 작성될 곳에 중복 작성을 하지 않고 참조를 통해서 동일한 효과를 거둘 수 있게 된다.

 

같은 네임스페이스를 가지는 스키마 문서의 결합이 가장 많이 사용되지만, 다른 네임스페이스를 가지는 스키마 문서의 결합도 가능하다. 스키마 언어에서 같은 네임스페이스를 가지는 스키마 문서의 결합에 사용되는 엘리먼트는 <include> 엘리먼트이고, 그리고 다른 네임스페이스를 가지는 스키마 문서의 결합에 사용되는 엘리먼트는 <import> 엘리먼트이다.

 

7.2 <include> 엘리먼트

네임스페이스가 같은 스키마 문서 또는 네임스페이스가 없는 스키마 문서를 결합하기 위해서 사용되는 엘리먼트는 <include> 엘리먼트이다. 다음은 <include> 엘리먼트의 작성 문법이다.

 

* 문법

<xsd:include schemaLocation="포함시킬 스키마 문서"/>

포함시킬 스키마 문서는 anyURI 타입으로 기술하면 된다. 즉 주 스키마 문서와 동일한 경로에 있을 경우에는 포함될 스키마 문서 이름만 언급하면 되고, 만약에 주 스키마 문서와 다른 경로에 포함될 스키마 문서가 있다면 다음과 같은 형태로 적어 주면 된다.

 

* 스키마 문서 경로 지정

schemaLocation="~.xsd"
schemaLocation="/경로명/.../~.xsd"
schemaLocation="http://웹서버주소/경로명/.../~.xsd" 

<include> 엘리먼트는 엘리먼트 선언 뒤나 속성 선언 뒤에 위치하면 유효한 스키마 문서가 되지 못한다. 보통은 루트 엘리먼트인 <schema> 엘리먼트 바로 밑에 작성된다.

다음은 비 문자 데이터인 그림 파일에 대한 포맷을 나타내는 노테이션을 속성값 및 데이터 값으로 사용할 수 있도록 하는 단순 타입을 정의한 스키마 문서 예제이다.

 

* 포함될 스키마 문서

<?xml version="1.0" encoding="euc-kr"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<!-- 글로벌 단순 타입의 정의 -->
<xsd:simpleType name="stType">
     <xsd:restriction base="xsd:NOTATION">
        <xsd:enumeration value="bmp"/>
        <xsd:enumeration value="gif"/>
        <xsd:enumeration value="jpeg"/>
     </xsd:restriction>
</xsd:simpleType>

<!-- NOTATION 선언 -->
<xsd:notation name="bmp" public="image/bmp" system="mspaint.exe"/>
<xsd:notation name="gif" public="image/gif" system="photoshop.exe"/>
<xsd:notation name="jpeg" public="image/jpeg" system="photoshop.exe"/>
</xsd:schema>

(“05-0303.xsd”)

상기 스키마 문서를 결합하기 위해 다음 문법을 사용할 수 있다.

 

* 스키마 문서

<!-- 포함될 스키마 문서 지정 -->
<xsd:include schemaLocation="05-0303.xsd"/>

<!-- 포함될 스키마 문서에 있는 단순 타입 적용 -->
<xsd:attribute name="type" type="stType"/> 
 

7.3 <import> 엘리먼트

네임스페이스가 다른 스키마 문서를 결합하기 위해서 사용되는 엘리먼트는 <import> 엘리먼트이다. 다음은 <import> 엘리먼트의 작성 문법이다.

 

* 문법

<xsd:import namespace="포함할 스키마 문서의 네임스페이스"
            schemaLocation="포함할 스키마 문서"/>

namespace 속성값은 참조할 스키마 문서의 네임스페이스 이름을 지정해 주면 된다. 그리고 schemaLocation 속성값은 포함시킬 스키마 문서에 대한 anyURI 타입 경로명을 기술해 주면 된다. 즉 주 스키마 문서와 동일한 경로에 있을 경우에는 포함될 스키마 문서 이름만 언급하면 되고, 만약에 주 스키마 문서와 다른 경로에 포함될 스키마 문서가 있다면 7.2 절에서 언급한 [스키마 문서 경로 지정] 형태로 적어 주면 된다.

<import> 엘리먼트는 글로벌 엘리먼트 선언이나 속성 선언 보다도 먼저 작성되어야 한다. 즉 엘리먼트 선언 뒤나 속성 선언 뒤에 위치하면 유효한 스키마 문서가 되지 못한다. 보통은 루트 엘리먼트인 <schema> 엘리먼트 바로 밑에 작성된다.

 

7.4 <redefine> 엘리먼트

같은 네임스페이스를 가지거나 네임스페이스가 없는 스키마 문서를 결합할 때 포함할 외부 스키마 문서의 일부를 재정의해서 결합할 수 있다. 이것은 외부 스키마 문서 자체를 수정하는 것이 아니라 포함하는 과정에서 동적으로 재 정의한 후 주 스키마 문서에 포함하는 것을 말한다.

재 정의될 수 있는 부분은 글로벌 단순 타입과 글로벌 복합 타입, 그룹, 속성 그룹에 해당이 된다. 이때 사용되는 엘리먼트가 <redefine> 엘리먼트이다.

 

* 문법

<xsd:redefine schemaLocation="포함할 스키마 문서">
     재정의
</xsd:redefine>
 주의할 점은 다른 네임스페이스를 가지는 스키마 문서는 동적으로 재 정의한 후 포함시킬 수 없다는 것이다.

다음은 사람에 대한 정보를 표현하는 구조를 정의한 스키마 문서이다.

 

* 포함될 스키마 문서

<?xml version="1.0" encoding="euc-kr"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<!-- 글로벌 단순 타입 정의 -->
<xsd:complexType name="ctPerson">
         <xsd:sequence>
             <xsd:element name="name" type="xsd:string"/>
             <xsd:element name="ssn" type="xsd:string"/>
             <xsd:element name="tel" type="xsd:string"/>
             <xsd:element name="address" type="xsd:string"/>
         </xsd:sequence>
     </xsd:complexType>
</xsd:schema> 

(“05-0304.xsd”)

 

상기 스키마 문서에 정의되어 있는 복합 타입에서 <name><tel> 엘리먼트 선언만 필요하고 나머지는 필요 없을 경우 다음과 같이 재정의해서 포함시키면 된다.

 

* 스키마 문서

<xsd:redefine schemaLocation="05-0304.xsd">
     <xsd:complexType name="ctPerson">
         <xsd:complexContent>
             <xsd:restriction base="ctPerson">
                 <xsd:sequence>
                     <xsd:element name="name" type="xsd:string"/>
                     <xsd:element name="tel" type="xsd:string"/>
                 </xsd:sequence>
             </xsd:restriction>
         </xsd:complexContent>
     </xsd:complexType>
<xsd:redefine>

정리하기

엘리먼트의 내용 또는 속성값으로 어떤 종류의 정보가 어떤 형태로 작성될 것인지를 결정하는 것이 데이터 타입이며, XML 스키마의 데이터 타입은 미리 정의한 빌트인 타입과 사용자 정의 데이터 타입으로 분류할 수 있다.

 

빌트인 데이터 타입은 XML 스키마 표준에서 스키마 문서 작성자의 편리성을 위해서 미리 정의한 데이터 타입이며 별도의 정의 없이 해당 데이터 타입이 사용 가능하다.

 

단순 데이터 타입을 정의하기 위해서는 <simpleType> 엘리먼트를 사용하며제한(restriction), 목록(list), 공용(union)을 이용해서 확장할 수 있다.

 

엘리먼트를 정의하고 사용하기 위해서 기본적으로 복합 데이터 타입(complexType)을 정의하여 사용한다. , 자식 엘리먼트나 속성을 필요로 하는 엘리먼트를 정의하기 위해서는 복합 데이터 타입으로 정의한다.

 

유일 제약이란 중복된 값을 가지지 않도록 제한하는 것을 말하며, 스키마에서는 ID 속성 타입뿐만 아니라 <key> 및  <unique> 엘리먼트를 사용해서 유일 제약을 정의할 수 있다.

정의된 속성값은 파서에 의해서 중복된 데이터가 입력되었는지 검증이 이루어지고, 중복된 값이 발견되면 유효하지 않은 문서로 취급된다.

 

노테이션(notation)은 그림 파일이나 동영상 파일, 음악 파일의 포맷을 식별하기 위해서 사용되는 특별한 엘리먼트로 MIME 타입과 유사한 기능을 한다고 보면 된다. XML 파서가 해석할 수 없는 비 문자 데이터가 어떤 종류의 포맷을 가지고 있고, 이 데이터를 처리할 수 있는 헬퍼 프로그램은 어떤 것인지를 응용프로그램에게 알려줌으로써 응용프로그램이 비 문자 데이터를 어떻게 처리할지를 결정할 수 있도록 해 주는 것이다.

 

같은 네임스페이스를 가지는 스키마 문서를 결합하기 위해서는 <include> 엘리먼트, 다른 네임스페이스를 가지는 스키마 문서의 결합을 위해서는 <import> 엘리먼트를 사용한다또한 <redefine> 엘리먼트를 사용하면 외부 스키마 문서의 일부분을 재정의해서 결합시킬 수 있다.

'정보과학 > 웹서비스특론' 카테고리의 다른 글

SOAP API  (0) 2023.09.08
SOAP  (0) 2023.09.07
XML 스키마 (1)  (0) 2023.09.05
XML 네임스페이스  (0) 2023.09.05
XML 문법  (0) 2023.09.04