# XML Schema의 구조
XML Schema는 그 자체가 XML 문서이며, XML과 동일한 문법을 이용한다.
1. 기본구조
<schema> root element와 namespace 선언을 갖는다.
<?xml version="1.0" encoding="EUC-KR"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
</xs:schema>
2. system에 문서 정보의 제공
스키마에 대한 정보를 문서화하는 표준화된 방법을 제공.
스키마를 처리하는 application이 이 정보를 처리.
<?xml version="1.0" encoding="EUC-KR"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:documentation>
이 문서는 그룹 목록에 대한 스키마를 설명한다.
</xs:documentation>
<xs:appinfo>
<config xmlns="http://www.example.com/externalapp">
<customertype>pop culture</customertype>
<destination id="I43"/>
</config>
</xs:appinfo>
</xs:annotation>
</xs:schema>
3. 스키마 문서의 사용
스키마 문서(XML문서에 대한 XML Schema가 정의되어 있는 문서) - 인스턴스 문서(XML 문서)
<?xml version="1.0" encoding="EUC-KR"?>
<collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="collectibles.xsd">
</collection>
# 단순 element
XML Schema에서는 <element> element로 element를 정의.
element에 data type을 지원할 수 있다.(현재 44개의 내장 data type 지원)
<xs:element name="description" type="xs:string"/>
<xs:element name="originDate" type="xs:date"/>
<xs:element name="numOwners" type="xs:positiveInteger"/>
1. 내장 data type
. 문자열 : string, normalizedString, token
. 정수 : byte, unsignedByte, integer, positiveInteger, negativeInteger, nonNegativeInter, nonPositiveInteger, int, unsignedInt, long, unsignedLong, short, unsignedShort
. 소수 : float, double
. boolean : Boolean
. 날짜/시간 : gMonth, gYear, gYearMonth, gDay, gMonthDay, duration, time, dateTime, date
. binary : base64Binary, hexBinary
. DTD 호환성 : attribute만 사용 가능. ID, IDREF, IDREFS, ENTITY, ENTITIES, NOTATION, NMTOKEN, NMTOKENS
. namespace 연관 : QName, NCName
. 그 외 : anyURI, lang, Name
2. 고정값과 기본값
<xs:element name="obtainable" type="xs:string" fixed="yes"/>
<xs:element name="originalOwner" type="xs:string" default="unknown"/>
변환과정
<obtainable/> => <obtainable>yes</obtainable>
<originalOwner/> => <originalOwner>unknown</originalOwner>
일반 entity를 대체하여 이용되는 경우
<xs:element name="copy" fixed="@"/>
<rights>Copyright <copy/>2003</rights>
# 복합 element
element내에 element가 포함되는 경우를 복합 타입으로 간주.
1. 자식 element의 정의
<?xml version="1.0" encoding="EUC-KR"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="obtainable" type="xs:string" fixed="yes"/>
<xs:element name="originalOwner" type="xs:string" default="unknown"/>
<xs:element name="collection">
<xs:complexType>
<xs:sequence> <- element들이 순서대로 나타나야 한다. <xs:all> 로 하면 임의의 순서로 나타난다.
<xs:element name="toys" type="xs:string"/>
<xs:element name="furniture" type="xs:string"/>
<xs:element name="pottery" type="xs:string"/>
<xs:element name="autographs" type="xs:string"/>
<xs:element name="advertising" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="EUC-KR"?>
<collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="collectibles.xsd">
<toys></toys>
<furniture></furniture>
<pottery></pottery>
<autographs></autographs>
<advertising></advertising>
</collection>
자식 element의 선택
<?xml version="1.0" encoding="EUC-KR"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="obtainable" type="xs:string" fixed="yes"/>
<xs:element name="originalOwner" type="xs:string" default="unknown"/>
<xs:element name="collection">
<xs:complexType>
<xs:choice> <- DTD에서의 '|'와 같은 기능
<xs:element name="toys" type="xs:string"/>
<xs:element name="furniture" type="xs:string"/>
<xs:element name="pottery" type="xs:string"/>
<xs:element name="autographs" type="xs:string"/>
<xs:element name="advertising" type="xs:string"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
2. 출연 횟수의 제어
minOccurs와 maxOccurs attribute를 사용하여 특정 element의 출현 횟수를 제어할 수 있다.
sequence, choice, all element와 minOccurs, maxOccurs attribute를 적절히 취합하여 구성가능
<xs:element name="previousOwner" type="xs:string" minOccurs="0" maxOccurs="5"/>
<xs:element name="collection">
...
<xs:choice minOccurs="1" maxOccurs="unbounded">
</xs:choice>
</xs:element>
3. 혼합 contents
complexType element에 mixed attribute를 사용.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="collection">
<xs:complexType mixed="false">
<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:element name="toys">
<xs:complexType>
<xs:sequence>
<xs:element name="previousOwner" type="xs:string" minOccurs="0" maxOccurs="5"/>
<xs:element name="description"
<xs:complexType mixed="true">
<xs:choice maxOccurs="unbounded">
<xs:element name="condition" type="xs:string"/>
<xs:element name="brand" type="xs:string"/>
<xs:element name="tradeName" type="xs:string"/>
</xs:choice>
</xs:complexType>
<xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
4. anyType
DTD의 ANY 타입 element와 동일한 기능을 수행하며, anyType으로 선언된 element는 contents model에 어떤 text 값도 가질 수 있다.
<xs:element name="condition" type="xs:string"/>
<xs:element name="brand" type="xs:string"/>
<xs:element name="tradeName" type="xs:string"/>
<xs:element name="collection">
<xs:element name="description" type="xs:anyType"/>
</xs:element>
description이 anyType으로 설정되어있기 때문에
description element 외부에 선언되어 있는 condition, brand, tradeName element를 자식 element로 가질 수 있다.
# 미리 정의된 element 들의 참조
element에 대한 참조
<xs:element name="condition" type="xs:string"/>
ref attribute를 이용해서 참조
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="condition" minOccurs="0" maxOccurs="5"/>
</xs:sequence>
</xs:complexType>
</xs:element>
참조되는 element들의 fixed, default attribute 등은 element 선언 내에서 정의되며,
minOccurs, maxOccurs attribute는 element를 참조하는 위치에서 정의된다.
전역으로 정의된 element를 참조 형식으로 이용하는 경우 element 선언의 재사용이 가능하다.
1. 범위의 설정
동일한 이름을 갖는 element는 상위 element의 범위 내에서만 유효하다.
전역 선언된 item element와 pottery element 내부에 선언된 item element가 있을 경우
pottery element 내부에 선언된 item element에 material 이라는 element를 하나 추가할 경우
material element를 갖는 item element는 pottery element 내부에서만 유효하다.
2. element group의 설정
<xs:group name="itemCommon">
<xs:sequence>
<xs:element ref="previousOwner" minOccurs="0" maxOccurs="5"/>
<xs:element ref="description"/>
<xs:element ref="originDate"/>
<xs:element ref="numOwners"/>
<xs:element ref="obtainable"/>
<xs:element ref="originalOwner"/>
</xs:sequence>
</xs:group>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:group ref="itemCommon"/>
</xs:sequence>
</xs:complexType>
</xs:element>
....
<xs:element name="pottery">
<xs:complexType>
<xs:sequence>
<xs:element name="item" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:group ref="itemCommon"/>
<xs:element name="material" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
# attribute의 정의
attribute element를 통해 선언
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:group ref="itemCommon"/>
</xs:sequence>
<xs:attribute name="itemid" type="xs:integer"/>
<xs:attribute name="keeper" type="xs:integer"/>
<xs:attribute name="demand" type="xs:integer"/>
<xs:attribute name="legal" type="xs:integer"/>
</xs:complexType>
</xs:element>
XML schema의 모든 내장 data type을 이용할 수 있다.
1. attribute의 속성 결정
DTD : #REQUIRED #IMPLIED #FIXED
XML schema : use, default, fixed
<xs:attribute name="itemid" type="xs:integer" use="required"/>
<xs:attribute name="keeper" type="xs:string" default="yes"/>
<xs:attribute name="demand" type="xs:string" use="optional"/>
<xs:attribute name="legal" type="xs:string" fixed="yes"/>
use, default, fixed는 attribute 선언에서 함께 사용될 수 없다.
2. attribute의 전역 선언과 attribute group
<xs:attribute name="itemid" type="xs:integer"/>
<xs:attribute name="keeper" type="xs:string"/>
<xs:attribute name="demand" type="xs:string"/>
<xs:attribute name="legal" type="xs:string"/>
ref를 이용하여 참조한다.
<xs:attribute ref="itemid" use="required"/>
attribute의 group의 선언에서 group에 포함될 attribute들은 미리 선언되어 있어야 한다.
<xs:attribute name="itemid" type="xs:integer"/>
<xs:attribute name="keeper" type="xs:string"/>
<xs:attribute name="demand" type="xs:string"/>
<xs:attribute name="legal" type="xs:string"/>
<xs:attributeGroup name="itemAtts">
<xs:attribute ref="itemid" use="required"/>
<xs:attribute ref="keeper" default="yes"/>
<xs:attribute ref="demand" use="optional"/>
<xs:attribute ref="legal" fixed="yes"/>
</xs:attributeGroup>
attribute group의 사용
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:group ref="itemCommon"/>
</xs:sequence>
<xs:attributeGroup ref="itemAtts"/>
</xs:complexType>
</xs:element>
# 새로운 타입의 생성
내장 data type 외에 새로운 type을 사용자가 정의할 수 있다.
범위 값 등 단순한 것부터 element와 attribute 들을 포함하는 계층 구조 같은 복잡한 type도 가능.
1. 이름이 부여된 type
복합 type을 선언하고, 이 선언에 대해 이름을 부여
<xs:complexType name="itemType">
<xs:sequence>
<xs:group ref="itemCommon"/>
</xs:sequence>
<xs:attributeGroup ref="itemAtts"/>
</xs:complexType>
...
<xs:element name="item" type="itemType" minOccurs="0" maxOccurs="unbounded"/>
2. 제약 사항의 부여
내장 data type에 여러가지 제약 사항을 추가함으로써 새로운 type을 생성할 수 있다.
<xs:simpleType name="USCurrency">
<xs:restriction base="xs:decimal>
<xs:fractionDigits value="2"/>
</xs:restriction>
</xs:simpleType
<xs:element name="originalPrice" type="USCurrency"/>
XML schema에서 제공하는 facet
minInclusive : 수의 최소값. 이상
minExclusive : 초과해야 하는 최소값. 초과
maxInclusive : 수의 최대값
maxExclusive : 미만이어야 하는 최대값
totalDigits : 소수점 앞,뒷자리를 포함한 수의 전체 자릿수 지정
fractionDigits : 소수점 뒷자리 수 지정
length : 값의 길이 지정
minLength : 문자형 데이터의 최소 길이
maxLength : 문자형 데이터의 최대 길이
pattern : 문자열 정보에 대한 정규 표현식
enumeration : 나열형 데이터에 대한 표기
whiteSpace : line feed, tab, carriage return 같은 특수 문자 처리. preserve(그대로), replace(한 개의 공백으로 대체), collapse(여러 개의 공백으로 대체)
- 나열형 타입
element와 attribute에 대한 선택을 제한
<xs:attribute name="demand">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="low"/>
<xs:enumeration value="medium"/>
<xs:enumeration value="high"/>
<xs:enumeration value="money is no object"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
demand attribute의 값은 low, medium, high, money is no object 중 하나만 선택되어야 한다.
- List 타입
공백으로 구분되는 여러 개의 값을 포함할 수 있다.
<xs:simpleType name="possibleOutlets">
<xs:restriction base="xs:string">
<xs:enumeration value="oBoy"/>
<xs:enumeration value="YoHoo!"/>
<xs:enumeration value="ConJunction"/>
<xs:enumeration value="Anazone"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="outletList">
<xs:List itemType="possibleOutlets"/>
</xs:simpleType>
<xs:simpleType name="outlets">
<xs:restriction base="outletList">
<xs:maxLength value="3"/>
</xs:restriction>
</xs:simpleType>
<item itemid="1">
....
<outlets>oBoy Yoohoo!</outlets>
</item>
3. 확장을 통해 단순 타입에 attribute 추가
<xs:element name="originalOwner">
<xs:complexType> <- element를 갖고 있기 때문에 복합타입으로 contents model 선언
<xs:simpleContent> <- 자식 element 없이 text 정보만을 가는 단순 컨텐츠만 취한다
<xs:extension base="xs:string">
<xs:attribute name="confirmed" default="no"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
# custom type 의 유도
custom type의 확장
<xs:complexType name="itemType">
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
<xs:complexType name="potteryItemType">
<xs:complexContent>
<xs:extension base="itemType"> <- itemType을 상속
<xs:sequence>
<xs:element name="material" type="xs:string"/> <- element 하나 추가
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
...
<xs:element name="item" type="potteryItemType" minOccurs="0" maxOccurs="unbounded"/>
...
1. 제약을 통한 타입의 유도
복합 타입에 대한 제약 사항의 부여
<xs:complexType name="advertisingItemType">
<xs:complexContent>
<xs:restriction base="itemType">
<xs:sequence>
<xs:element href="previousOwner" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
...
<xs:element name="item" type="advertisingItemType" minOccurs="0" maxOccurs="unbounded"/>
...
제약과 확장
<xs:complexType name="autographRestrictType">
<xs:complexContent>
<xs:restriction base="itemType">
<xs:sequence>
<xs:element ref="previousOwner" minOccurs="5" maxOccurs="5"/>
...
<xs:element name="lastPrice" type="USCurrency"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complextType>
<xs:complexType name="autographItemType">
<xs:complexContent>
<xs:extension base="autographRestrictType"> <- autographRestrictType을 상속 받음
<xs:sequence>
<xs:element name="description" type="xs:string"/> <- description, personFirst element 추가
<xs:element name="personFirst" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
원래 있는 element를 재정의 하기 xs:restriction
원래 있는 element에 element를 추가하기 위해서는 xs:extension 사용
# 데이터 무결성
1. 유일 키의 지원
XML schema는 데어터 무결성을 지원한다.
<xs:unique name="itemIdKey">
<xs:selector xpath=".//item"/>
<xs:field xpath="@itemid"/>
</xs:unique>
2. key 와 keyref
DB의 foreign key 역할
foreign key : 한 relation에 대한 primary key로, 반드시 나타나야 하는 값이면서 다른 relation에서 이를 참조하는 키 값
<xs:element name="onSale">
<xs:complexType>
<xs:sequence>
<xs:element name="itemForSale" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="outlet" type="outlets"/>
<xs:element name="itemid" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:keyref name="onSaleItems" refer="existingItems">
<xs:selector xpath="."/>
<xs:field xpath="itemid"/>
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:unique>
<xs:key name="existingItems">
<xs:selector xpath=".//item"/>
<xs:field xpath="@itemid"/>
</xs:key>
# namespace의 지원
1. noNamespaceSchemaLocation
namespace 접어를 이용하지 않으려 할 경우
<collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="collectibles.xsd">
2. targetnamespace
스키마 문서에서 정의하는 element가 특정 namespace에 속해야 할 필요가 있을 경우
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:col="http://www.example.com/collection"
targetNamespace="http://www.example.com/collection"
elementFormDefault="qualified"
attributeFormDefault="qualified"
>
3. 다중 namespace
다른 namespace에 속하는 element 정의의 이용
<?xml version="1.0" encoding="EUC-KR"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:col="http://www.example.com/collection"
xmlns:spec="http://www.example.com/spec"
targetNamespace="http://www.example.com/collection"
elementFormDefault="qualified"
attributeFormDefault="qualified"
>
...
<complexType name="itemType">
<sequence>
<element ref="col:previousOwner" minOccurs="0" maxOccurs="5"/>
<element ref="spec:specifications" minOccurs="0"/>
</sequence>
</complexTyhpe>
...
다중 namespace의 참조
<?xml version="1.0" encoding="EUC-KR"?>
<c:collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.example.com/collection"
xmlns:s="http://www.example.com/spec"
xsi:schemaLocation="http://www.example.com/collection collectibles.xsd
http://www.example.com/spec specs.xsd">
<c:toys>
<c:item c:itemid="1" c:demand="money is no object">
<c:previousOwner>John Sorhed</c:previousOwner>
<c:description>
This piece is a genuine wooden <c:brand>Silhaven</c:brand>
.....
</c:description>
<s:sepcifications>The specifications are...</s:specification>
<c:originDate>1940</c:originDate>
</c:item>
</ctoys>