XML Schema 번역 작업중입니다.(서울대학교 산업공학과 정보시스템 연구실 석사 2학기 김명환) -- e-mail : kovra@netopia.snu.ac.kr
XML Schema는 web service의 필수요소인 UDDI, WSDL 스펙을 이해하기 위해 매우 중요합니다.
W3C XML Schema Part 1 : structure와 W3C XML Schema Part 1 : dataType, UDDI 스펙, WSDL 스펙도 번역중에 있습니다.
W3C XML Schema Part 0 : Primer
W3C Recommendation , 2, May 2001
Copyright© 2001 W3C(MIT,INRIA,Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply
Abstract
XML Schema Part 0 : 입문서는 어떤 XML Schema에 관한 쉬운 설명을 제공하고 XML Schema Language를 이용하여 스키마를 작성하는 방법을 빠르게 이해시키기 위한 목적으로 만들어 졌다. XML Schema Part 1: Structures 와 XML Schema Part2 : Datatypes 은 XML Schema Language 표준에 관한 모든 설명을 해준다. 이 입문서는 많은 예를 통해 XML Schema Language에 관한 특징을 설명하고 있다.
Table of contents
여기에 테이블을 만들어 넣을 것!
1. introduction
이 문서, XML Schema Part 0 : 입문서는 XML Schema definition language에 쉽게 접근할 수 있는 방법을 제공한다. 그리고 XML Schema 스펙 Part1 과 Part2에 포함된 XML Schema definition language의 표준 스펙을 참조하면서 읽을 수 있도록 구성되어 있다. 이 문서가 목표로 하는 대상은 DTD가 제공하는 기능들에 관한 한계를 느껴 Schema 문서를 읽고 쓰도록 프로그램을 작성해야 하는 프로그램 개발자, XML Schema의 특성에 관해 알아야 하는 Schema 제작자등이 될 수 있을 것이다. 이 입문서는 이 글을 읽는 당신이 XML1.0과 XML-Namespace에 관한 기본적인 지식이 있다고 가정한다. 입문서의 각 부분은 XML Schema definition language의 새로운 특징을 소개하고 구체적인 예를 통하여 이러한 특징을 기술하여 여러분의 이해를 도울 것이다.
Section2는 XML Schema에 관한 기본적인 메커니즘을 제공한다. XML문서에서 나타나는 element와 attribute를 선언하는 방법, simple type과 complex type의 차이, element와 attribute에 있어 simple type의 사용, schema 주석처리, element와 attribute 정의를 재 사용하는 간단한 메커니즘등을 보일 것이다.
Section3는 입문서의 첫 번째 고급단계로서 namespace가 XML과 Schema문서에서 어떻게 사용되는지 설명한다. Section3는 다른 고급단계에서 나타나는 많은 topic들을 이해하기 위해 매우 중요한 단계이다.
Section4는 입문서의 두 번째 고급단계로서 기존의 type들로부터 새로운 타입을 만들어 내거나 이렇게 유도된 타입들을 제어하기위한 메커니즘을 설명한다. 또한 여러 source로부터 Schema의 일부분들을 모아 하나로 합치는 것과 element substition에 대한 메커니즘도 제공한다.
Section5는 좀더 attribute와 element사이에 유일성을 구체화 시키는 메커니즘, namespace를 가로질러 type들을 이용하는 방법, 그리고 문서가 어떻게 일치하는 가를 체크는지에 대한 설명등 좀더 난이한 특성들을 살펴볼 것 이다.
위에 있는 Section가 더불어 이 입문서는 simple types과 regular expression language에 대한 세세한 참조 정보를 제공하는 많은 부록을 포함하고 있다.
이 입문서는 표준적인 문서가 아니다. 즉 XML Schema에 정의된 스펙을 제공하지는 않는다. 입문서에 나타나는 여러 예들과 설명자료들은 XML Schema를 쉽게 이해하도록 돕지만 항상 스펙에 정의된 모습을 띄지는 않는다. 그러한 경우에 있어 XML Schema 스펙을 참조하는 것이 좋을 것이며 우리는 문서의 여러부분에서 XML Schema 스펙에 관한 링크를 통해 여러분이 쉽게 XML Schema 스펙을 찾아보도록 하였다.
2. Basic Concepts : The Purchase order
Schema의 목적은 XML 문서에 대한 골격(뼈대)을 제공하는 것이며 "instance document"란 용어는 어떤 특정 schema와 일치하는 XML 문서를 가르키는데 종종 사용되곤 한다(객체 지향 개념에서 class와 instance와 비슷하다고나 할까 - 물론 차이가 있지만). 사실 instance도 schema도 문서로서 존재할 필요가 없다.(아마 application사이에 주고 받는 일련에 bytes로 존재하거나 데이터베이스에 있는 어떤 필드값으로 존재할 수 도 있다.) 하지만 이 입문서에서는 여러 가지 복잡한 상황을 단순화하기 위해서 항상 문서나 파일인 것처럼 instance와 schema를 언급할 것이다.
po.xml에 있는 instance 문서를 고려하는 것부터 시작해보자. instance 문서는 생활용품 주문과 지불 application에 의해 만들어지는 구매주문서이다.
|
The Purchase Order , po.xml |
<?xml version="1.0"?>
<purchaseOrder orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Mill Valley</city>
<state>CA</state>
<zip>90952</zip>
</shipTo>
<billTo country="US">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Old Town</city>
<state>PA</state>
<zip>95819</zip>
</billTo>
<comment>Hurry, my lawn is going wild!</comment>
<items>
<item partNum="872-AA">
<productName>Lawnmower</productName>
<quantity>1</quantity>
<USPrice>148.95</USPrice>
<comment>Confirm this is electric</comment>
</item>
<item partNum="926-AA">
<productName>Baby Monitor</productName>
<quantity>1</quantity>
<USPrice>39.98</USPrice>
<shipDate>1999-05-21</shipDate>
</item>
</items>
</purchaseOrder>
|
Purchase order XML 문서는 주 element인 purchaseOrder와 subelement인 shipTo, billTo, comment, items으로 구성되어 있다. 이러한 subelement들은 그안에 다른 subelement와 attribute들을 포함하고 있다. 보는 바와 같이 USPrice와 같은 element는 그안에 다른 subelement를 포함하고 있지 않고 단지 숫자만을 포함하고 있다. subelement와 attirbute를 포함하는 element를 complex type을 가졌다고 말하고 반면에 숫자나 날짜, 문자열등을 포함하고 있지만 어떤 subelement도 포함하고 있지 않은 element를 simple type을 가졌다고 말한다. 어떤 element들은 attribute을 갖는다.(attribute는 항상 simple type을 갖는다 - element나 다른 attribute를 포함할 수 없기 때문에..) instance 문서에서의 complex type과 몇몇 simple type들이 purchase order schema에 정의된다. 다른 simple type들은 이미 만들어져 정의되어져 있다.
Purchase order schema를 보기전에 purchase order instance 문서(po.xml)와 purchase order schema(po.xsd)사이의 관계를 간단히 언급하고 지나가겠다. purchase order instance 문서를 보면 purchase order schema가 전혀 언급되어져 있지 않다.(어떻게 schema 문서를 참고해서 유효성을 검증해야 할 지). 사실 여러분도 알다시피 XML 문서가 꼭 DTD나 Schema를 필요로 하는 것은 아니다. 이러한 경우에 있어 잘만들어진 문서를 well-formed XML 문서라고 한다. 하지만 DTD나 Schema를 XML 문서에서 사용하기 위해서는 꼭 두 문서간에 링크가 필요하다. 많은 XML 문서들이 이런식으로 그 유효성을 검증하고 있다. 하지만 이 입문서에서 사용되고 있는 purchase order instance 문서는 두 문서간의 어떤 링크 없이도 그 유효성 검증이 가능하다라고 가정한다(단순화를 위해서). 뒷 부분에서 instance와 schema를 연결시키는 명백한 메커니즘을 보일 것이다( 물론 많은 분들이 이미 아시겠지만 ...)
2.1 The Purchase Order Schema
|
The Purchase Schema, po.xsd |
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Purchase order schema for Example.com.
Copyright 2000 Example.com. All rights reserved.
</xsd:documentation>
</xsd:annotation>
<xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
<xsd:element name="comment" type="xsd:string"/>
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:complexType name="USAddress">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="partNum" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<!-- Stock Keeping Unit, a code for identifying products -->
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
|
purchase order schema는 schema element와 element, complexType, simpleType과 같은 많은 subelement들로 구성되어 있다. 모든 element들은 xsd:라는 접두사를 가지고 있는데 이는 Schema element의 xmlns:xsd="http://www.w3.org/2001/XMLSchema"를 통한 namespce의 선언과 관련이 있다. xsd: 라는 접두어를 통해 우리는 다른 element 네임과 중복되지 않는 element를 선언하게 되는 것이다(자세한 내용은 후반부에...)
2.2 Complex Type Definitions, Element & Attribute Declarations
XML Schema는 complex type(그 안에 subelement들과 attribute들을 포함하는 것을 허락한다)과 simple type(element를 포함할 수 없으며 attribute 또한 포함시킬 수 없다)으로 기본적으로 분류하고 또 새로운 타입을 만드는 정의인가 아니면 기존에 있는 element와 attribute를 이용하는 선언인가에 따라 분류하기도 한다. 이 부분에서는 complex type을 정의하고 그것 안에서 나타나는 element와 attribute을 선언하는데 초점을 맞추어 글을 전개해 나가도록 하겠다.
새로운 complex type은 complexType element를 이용하여 정의하며 그러한 complex type정의에는 일반적으로 element 선언, element 참조, attribute 선언등이 포함된다. element는 element element를 사용해 선언되고 attribute는 attribute element를 통해 선언되어 진다. 예를 들어 USAddress는 complex type으로 정의되어졌고 그 안에 5개의 element 선언과 1개의 attribute선언을 가지고 있는 것을 볼 수 있다.
|
Defining the USAddress Type |
<xsd:complexType name="USAddress" >
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
|
이러한 정의의 결과는 다음과 같다. type이 USAddress로 정의되어져 있는 instance 문서(XML 문서들)에서 나타나는 어떤 element도 5개의 element와 1개의 attribute를 가져야 한다. subelement의 name부분에 각각의 element에 대한 이름이 선언되었으며 이 값이 XML 문서에 나타나야 하고 그 순서를 지켜야 한다. 첫 번째 4개의 element는 문자열을 표현할 것이며 다섯 번째 element는 숫자를 포함할 것이다. 하나의 attribute가 포함되어 있는데 name은 country이고 문자열 US를 반드시 포함해야 할 것이다.
USAddress 정의는 string, decimal, NMTOKEN과 같은 단지 simple type만으로 구성된 선언들만 포함하고 있다. 반면에 PurchaseOrderType 정의는 USAddress와 같은 complex type을 포함하는 element 선언을 보여주고 있다. type이 complex type이건 simple type이건 간에 type 속성에 그 type을 넣어줌으로써 사용할 수 있다.
|
Defining PurchaseOrderType |
<xsd:complexType name="PurchaseOrderType" >
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
|
PurchaseOrderType에서 보면 shipTo, billTo는 비록 다른 element 이름을 갖지만 USAddress라는 갖은 complex type을 갖는다. 따라서 PurchaseOrderType이라고 선언된 type을 갖는 어떤 XML 문서도 그 안에 5개의 subelement를 갖는 shipTo, billTo라고 이름 붙여진 element를 포함해야 한다. PurchaseOrderType은 orderDate라 이름 붙여진 simple type으로 이루어진 attribute를 가지고 있다. 보는 바와 같이 attribute는 무조건 simple type으로 이루어져 있으며 그 안에 element나 다른 attribute를 포함할 수 없다.
새로운 element를 선언하는 것보다 기존 element를 이용하는 것이 더 나을 때가 있다.
|
<xsd:element ref="comment" minOccurs="0"/> |
이 선언은 purchase order schema의 어딘가에 선언되어 있는 element, comment를 참조하고 있다. 일반적으로 ref attribute의 값은 global element를 참조해야만 한다. 즉 global element는 complex type의 일부분으로 선언되어 있는 것 보다 Schema의 아래에 선언되어 있다. 위의 경우 comment element는 global element로 선언되어 있고 stirng 값을 가지고 있다. 따라서 comment element를 참조하는 element는 문자열 값을 가질 것이다.
2.2.1 Occurrence Constraints
comment element는 PurchaseOrderType에서 포함시켜도 되고 포함시키지 않아도 되는 선택적인 element이다. 그것은 comment element가 갖는 minOccurs attribute 때문인데 문서에서 보면 0의 값을 갖는 것을 볼 수 가 있다. 일반적으로 minOccurs attribute의 값이 1이거나 그 이상일 경우 그 element는 반드시 포함되어야 한다. maxOccurs attirbute를 사용해서 한 element가 포함되어질 수 있는 최대 수를 결정할 수 도 있다. maxOccurs가 가질 수 있는 값은 41과 같은 양의 정수이다. 그리고 unbounded라는 용어를 사용하여 최대값이 없는 무한의 element를 포함 시킬 수 있다는 것을 표현하기도 한다. minOccurs와 maxOccurs attribute의 default 값은 1이다. 따라서 comment와 같은 element가 maxOccurs없이 선언되었다면 그 element는 한번 이상 포함될 수 없다. minOccurs와 maxOccurs의 값을 단독으로 사용한다면 minOccurs attirbute의 값은 maxOccurs의 값과 같거나 작아야 한다. 즉 0 또는 1의 값을 가질 수 있다. 유사하게 단독으로 사용하는 환경에서 maxOccurs의 값을 채워준다면 그 값은 minOccurs의 값과 같거나 커야한다. 즉 1 또는 그 이상의 값을 가질 수 있다. maxOccurs와 minOccurs가 모두 생략된다면 그 element는 반드시 한번만 나타나야 한다.
attribute들은 1번 또는 전혀 나타나지 않을 수도 있다. element의 발생빈도를 정해주는 것과는 조금 차이가 있다. 즉 attribute의 값은 여러번 사용되지 않는다. attribute의 use attribute가 attribute의 발생빈도를 결정해 준다. use attribute는 required(반드시 필요한), optional(있어도 되고 없어도 되는), prohibited(반드시 없어야 되는) 세 개의 값을 가질 수 있다. element나 attribute 모두 default 값은 default attribute을 이용해 선언해 준다. Default attribute 값은 attribute가 생략되었을 때 적용되고 default element 값은 element가 비어있을 때 적용된다.
fixed attribute는 attribute와 element에서 모두 사용되어진다. 예를 들어 po.xsd는 country attribute의 선언을 포함하고 있으며 그 값은 US라는 고정된 값으로 선언되어져 있다. 이 선언이 의미하는 것은 이 schema를 사용하는 XML 문서에서 country attribute의 사용은 optional(use attribute의 default 값은 optional)이며 만약 country attribute가 사용된다면 그 값은 반드시 US가 되어야 한다는 것이다. 만약 attribute가 사용되지 않으면 schema processor는 자동적으로 country attribute에 US값을 제공할 것이다. fixed 값과 default 값을 사용하는 것은 상호 배타적이며 fixed 값과 default값을 동시에 사용하는 것은 에러를 유발할 것이다.
Table1은 element와 attribute에서 사용되는 Occurence Constraints에 대한 요약이다.
|
Table1. Occurence Constraints for Elements and Attributes | ||||
|
Attributes use,fixed,default |
Notes | ||
|
(1, 1) -, - |
required, -, - |
element와 attribute는 한번 나타나야 한다. 어떤 값을 가질 수 있다. | ||
|
(1, 1) 37, - |
required, 37, - |
element와 attribute는 한번 나타나야 한다. 37을 값으로 가져야 한다. | ||
|
(2, unbounded) 37, - |
n/a |
element는 2개 이상의 값을 가져야 한다. 37을 값으로 가질 것이다. minOccurs와 maxOccurs의 값은 일반적으로 양의 정수이고 maxOccurs는 또한 "unbounded"라는 용어를 값으로 가질 수 있다. | ||
|
(0, 1) -, - |
optional, -, - |
element와 attribute는 한번 나타나거나 안 나타날 수도 있다. 어떤 값이나 갖을 수 있다. | ||
|
(0, 1) 37, - |
optional, 37, - |
element와 attribute는 한번 나타나거나 안 나타날 수도 있다. 나타난 다면 37의 값을 가져야 하고 나타나지 않으며 그것의 값은 37이다. | ||
|
(0, 1) -, 37 |
optional, -, 37 |
element와 attribute는 한번 나타나거나 안 나타날 수도 있다. 나타나지 않으며 그것의 값은 37이고 그렇지 않으면 주어진 값을 같는다. | ||
|
(0, 2) -, 37 |
n/a |
element는 한번 또는 두 번 나타나거나 안나타날 수도 있다. element가 나타나지 않으면 그것은 제공되지 않는다. 그것이 나타난다면 그것의 값은 37이고 그렇지 않으면 주어진 값을 갖는다. | ||
|
(0, 0) -, - |
prohibited, -, - |
element/attribute가 표시되어서는 안된다. | ||
|
Global element와 attribute의 선언에 minOccurs, maxOccurs, use는 사용할 수 없다. | ||||
2.2.2 Global Elements & Attributes
Global elements, global attributes는 Schema element의 자식으로 선언함으로서 생성할 수 있다. 한번 선언되면 ref attribute를 이용하여 하나 이상의 선언에서 참조 할 수 있다. 또한 global element의 선언은 element가 instance 문서(XML 문서)의 top-level 에 보이는 것을 가능하게 만든다. 따라서 po.xsd에 global element로 선언된 PurchaseOrder는 po.xml에서 top-level element로 보일 수 있다. 마찬가지로 comment element도 po.xml에서 top-level element로 사용될 수 있다.
global element와 global attribute 사용과 관련한 많은 주의 사항이 있다. 그중 하나는 global element/attribute선언은 참조를 포함할 수 없다. 즉 global element/attribute선언은 simple type이나 complex type으로만 표현이 되어야 한다. 즉 ref attribute를 사용할 수 없고 반드시 type attribute를 이용해야 한다. 또다른 하나는 global element/attribute 선언은 minOccurs, maxOccurs, use 와 같은 cardinality constraint를 사용할 수 없다는 것이다.
2.2.3 Naming Conflicts
우리는 지금까지 어떻게 새로운 complex type을 정의(e.g. PurchaseOrderType)하고 element를 선언(e.g. PurchaseOrder)하며 attribute를 선언(e.g. orderDate)하는지에 관해 기술하였다. 여기서 우리는 name attribute에 각각 적절한 이름을 부여하였다. 만약 같은 name으로 두 개의 element나 attribute를 정의한다면 어떤 일이 발생하게 될까?
두가지가 모두 type이고 같은 이름을 가지면 naming conflict가 발생한다. 하나는 complex type, 또 하나는 simple type. complex type의 이름을 USStates라고 하고 다른 어떤 simplex type의 이름을 USStates라고 하면 naming conflict가 발생한다. 하나는 type이고 하나는 element라면 naming conflict가 발생하지 않는다. 하나는 complex type이고 이름을 USAddress라 갖고 또 하나는 element로 그 이름을 USAddress로 갖는다면 둘 사이에는 naming conflict가 발생하지 않는다. 다른 type안에 포함된 다른 element들이 갖은 이름을 갖는다면 naming conflict가 발생하지 않는다. 즉 하나는 USAddress type에서 street라는 이름을 갖는 element이고 다른 하나는 Item type에서 street라는 이름을 갖는다면 naming conflict가 발생한다. 둘다 type 이라 할지라도 XML schema가 다른 곳에 정의되어 있다면 naming conflict가 발생하지 않는다. 두 개가 다른 namespace를 갖기 때문이다.
2.3 Simple Types
Purchase order schema는 simple type을 갖는 몇몇 element와 attribute를 선언한다. string, decimal과 같은 simple type들은 XML schema에 이미 만들어져 있으며 몇몇은 여기에서 유도되어 만들어 진다. 예를 들어 po.xsd에서 SKU라고 불리는 type은 string으로부터 유도되어 만들어진 것이다. 이미 만들어진 simple type과 여기서 유도된 simple type들은 모든 element/attribute 선언에서 사용되어질 수 있다. Table2는 XML schema에서 이미 만들어져 있는 simple type의 예이다.
|
Table2. Simple Types Built In to XML Schema | |
|
Simple Type |
Examples(delimited by commas) |
|
string |
Confirm this is electric |
|
normalizedString |
Confirm this is electric |
|
token |
Confirm this is electric |
|
byte |
-1, 126 |
|
unsignedByte |
0, 126 |
|
base64Binary |
GpM7 |
|
hexBinary |
0FB7 |
|
integer |
-126789, -1, 0, 1, 126789 |
|
positiveInteger |
1, 126789 |
|
negativeInteger |
-126789, -1 |
|
nonNegativeInteger |
0, 1, 126789 |
|
nonPositiveInteger |
-126789, -1, 0 |
|
int |
-1, 126789675 |
|
unsignedInt |
0, 126789675 |
|
long |
-1, 12678967543233 |
|
unsignedLong |
0, 12678967543233 |
|
short |
-1, 12678 |
|
unsignedShort |
0, 12678 |
|
decimal |
-1.23, 0, 123.4, 1000.00 |
|
float |
-INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN |
|
double |
-INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN |
|
boolean |
true, false (1, 0) |
|
time |
13:20:00.000, 13:20:00.000-05:00 |
|
dateTime |
1999-05-31T13:20:00.000-05:00 |
|
duration |
P1Y2M3DT10H30M12.3S |
|
date |
1999-05-31 |
|
gMonth |
--05-- |
|
gYear |
1999 |
|
gYearMonth |
1999-02 |
|
gDay |
---31 |
|
gMonthDay |
--05-31 |
|
Name |
shipTo |
|
QName |
ps:USAddress |
|
NCName |
USAddres |
|
anyURI |
http://www.example.com |
|
language |
en-GB, en-US, fr |
|
ID |
|
|
IDREF |
|
|
IDREFS |
|
|
ENTITY |
|
|
ENTITIES |
|
|
NOTATION |
|
|
NMTOKEN |
|
|
NMTOKENS |
|
새로운 simple type은 기존의 simple type(이미 만들어져 있는 것, 유도된 것)에서부터 유도함으로서 만들 수 있다. 특별히 우리는 기존에 있던 simple type에 제약을 가함으로써 새로운 simple type을 만들어 낼 수 있다. 즉 새로운 타입의 규정 범위는 기존 simple type의 하위 집합일 수 있다. 우리는 새로운 simple type을 정의하기 위해서 simpleType element를 사용한다. simpleType element의 subelement로 restriction element는 기존의 type을 나타내고 값들의 범위에 제약을 주는 facets 들을 나타내기 위해 사용한다. 모든 facets들의 리스트는 부록 B에서 볼 수가 있다.
우리가 10000에서 99999사이의 값을 갖는 myInteger라는 새로운 type의 integer를 생성하고 싶다고 하자. base로 이미 만들어져 있는 simple type인 integer를 이용하면 좋을 것이다. myInteger를 정의하기 위해서 기본형(base type)인 Integer type에 minInclusive, maxInclusive라 불리는 facet을 사용하여 제한을 가한다.
|
Defining myInteger, Range 10000 - 99999 |
<xsd:simpleType name="myInteger">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="10000"/>
<xsd:maxInclusive value="99999"/>
</xsd:restriction>
</xsd:simpleType>
|
예에서 우리는 myInteger를 정의하기 위하여 기본형과 두 개의 facets을 사용하였다.
SKU 라 불리는 새로운 simple type은 simple type string에서 유도 되었다. 그리고 여기서 우리는 pattern이라 불리는 facet을 이용하여 SKU의 값에 제한을 가하였다.
|
Defining the Simple Type "SKU" |
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>
|
여기서 pattern은 값으로 d{3}-[A-Z]{2}를 값으로 갖는데 이것이 갖는 뜻은 "세자리 수 다음 하이픈(-)이 나오고 2개의 대문자 아스키 문자"가 나와야 한다고 제약하는 것이다. 부록 D에 더자세히 설명되어 있다.
XML Schema는 부록 B에 15개의 facet을 정의한다. 이중에서 enumeration facet은 매우 유용하며 boolean을 제외한 거의 모든 simple type의 값에 제약을 줄 수 있다. enumeration facet은 type이 가져야 하는 값들에 제한을 가하는데 매우 좋은 방법이다. 예를 들어 우리가 USState라 불리우는 새로운 simple type을 정의하기 위해 enumeration facet을 사용한다고 하자. string에서 유도되었으며 그 값은 미국 주의 축약어중 하나로 나타나야 한다.
|
Using the Enumeration Facet |
<xsd:simpleType name="USState">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="AK"/>
<xsd:enumeration value="AL"/>
<xsd:enumeration value="AR"/>
<!-- and so on ... -->
</xsd:restriction>
</xsd:simpleType>
|
USState는 현재 state element선언에서 이용되고 있는 simple type string을 대체할 수 있는 좋은 도구가 된다. 이렇게 바꿈으로서 billTo, shipTo의 subelement인 state가 갖을 수 있는 값은 AK, AL, AR, 등으로 제한되어진다.
2.3.1 List Types
XML schema는 Table 2에 나열된 대부분의 type을 구성하는 소위 atomic type 이외에 list type의 개념을 갖는다.(atomic type, list type, union type이 집합적으로 simple type이라 불리어진다.) atomic type의 값은 XML schema의 관점에 있어 쪼개어 질 수 없는 것을 말한다. 예를 들어 NMTOKEN 값 US는 쪼개어 질 수 없다. 이에 반해 list type은 atomic type들의 일련의 순서로 이루어져 있다. 결과적으로 순서가 있는 각각의 부분이 atom이 되고 이들 각각의 의미를 갖는다. 예를 들어 NMTOKENS는 list type이고 "US UK FR"과 같이 표현되며 공백이 각각의 atom을 구분해주고 있다. XML schema는 3개의 이미 만들어진 list type을 가지며 그것은 NMTOKENS, IDREFS, ENTITIES 이다.
이미 만들어져 있는 type이외에 지금 있는 atom type을 이용하여 새로운 list type을 만들 수 있다.(여기서 중요한 것은 기존의 list type에서 새로운 list type을 만드는 것은 아니라는 것이다.) 예를 들어 myInteger 리스트를 생성하기 위해서 다음과 같이 할 수 있다.
|
Creating a List of myInteger's |
<xsd:simpleType name="listOfMyIntType">
<xsd:list itemType="myInteger"/>
</xsd:simpleType>
|
XML 문서에서 이 만족시키는 element는 다음과 같이 나타날 것이다.
|
<listOfMyIntType>20003 15037 95977 95945</listOfMyIntType> |
length, minLength, maxLength, enumeration와 같은 facet들이 list type에 적용될 수 있다. 예를 들어 6개의 미국 주를 list type으로 정의하기 위해 USState로부터 USStateList라 불리우는 새로운 list type을 정의한다. 그리고 나서 USStateList를 단지 6개의 atom만 갖도록 제약하여 SixUSStates를 유도할 수 있다.
|
List Type for Six US States |
<xsd:simpleType name="USStateList">
<xsd:list itemType="USState"/>
</xsd:simpleType>
<xsd:simpleType name="SixUSStates">
<xsd:restriction base="USStateList">
<xsd:length value="6"/>
</xsd:restriction>
</xsd:simpleType>
|
SixUSState element는 반드시 6개의 item을 가져야 하며 각각의 값은 USState의 atom 값중 하나이어야 한다.
|
<SixUSStates>PA NY CA NY LA AK</SixUSStates> |
atom 중 string으로부터 list type을 유도하는 것이 가능하다. 하지만 문자열이라는 것 자체가 공백을 포함하고 있으므로 기본형을 string으로 사용할 때 각별한 주의가 요구된다. 예를 들어 기본형이 string이고 length facet이 3인 list type을 정의했다고 가정하면 다음과 같은 3개의 item list는 옳다.
| Asie Europe Afrique |
그러나 다음은 옳지 않다.
Asie Europe Amérique Latine |
"Amérique Latine"이 비록 하나의 string일 지라도 그 사이의 공백 때문에 list에는 결과적으로 4개의 item이 생성되었다.
2.3.2 Union Types
다양한 multiple atom type과 list type의 결합을 통해 하나의 Union type을 만든다. 예를 들어 미국의 주를 나타내기 위해 union type을 만든다고 하자. atom type인 축약어로 된 문자로도 표현할 수 있으며 list type인 zip code로도 표현할 수 있게 만들고 싶다. zipUnion type은 한 개의 atom type과 한 개의 list type으로 만들어 진다.
|
Union Type for ZipCodes |
<xsd:simpleType name="zipUnion"> <xsd:union memberTypes="USState listOfMyIntType"/> </xsd:simpleType> |
Union type을 정의할 때 memberTypes attribute는 union에 있어 모든 type들의 리스트이다. 이제 우리가 zipUnion type인 zips이라 불리우는 어떤 element를 선언했다고 하자. 다음은 유효한 element들이다.
<zips>CA</zips> <zips>95630 95977 95945</zips> <zips>AK</zips> |
2.4 Anonymous Type Definitions
Schema들은 PurchaseOrderType과 같이 일련의 이름을 갖는 type을 정의하고 "type=" 생성자를 이용해 그 type을 참조하는 purchaseOrder와 같은 element를 선언함으로써 만들어 질 수 있다. 이러한 형태의 schema 생성은 직관적이지만 너무 무거워서 다루기 힘들고 특별히 제약을 거의 포함하지 않는다면 단지 한번 참조되는 많은 type을 정의하는데는 매우 비효율적이다. 이러한 경우에 있어 type은 간결하게 anonymous type으로 정의할 수 있다. po.xsd에서의 complex type인 Items은 anonymous type을 이용하는 두 개의 element(item, quantity)를 선언하고 있다. 일반적으로 element 선언에서 "type="이 없으면 anonymous type이라고 할 수 있다.
|
Two Anonymous Type Definitions |
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="partNum" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
|
item element는 element인 productName, quantity, USPrice, comment 그리고 shipDate, attribute인 partNum으로 구성된 anonymous complex type을 갖는다. quantity element의 경우 1과 99사이의 값을 갖는 integer로부터 파생된 anonymous simple type을 갖는다.
2.5 Element Content
Purchase order schema는 다른 element를 포함하는 element(e.g.items), attribute를 갖고 다른 element를 포함하는 element(e.g.shipTo), 그리고 단순히 simple type만을 포함하는 element등 많은 element들의 예를 보여준다. 하지만 attribute를 갖지만 simple type element만 포함하는 element, 전혀 내용을 갖지 않는 element등은 보지 못했다. 이 부분에서 element가 갖는 content에 대한 다양한 사례를 살펴 볼 것이다.
2.5.1 Complex Types from Simple Types
우선 하나의 attribute를 갖고 하나의 simple 값을 갖는 element를 살펴보도록 하자. XML 문서에서 그러한 element는 다음과 같이 나타날 지 모른다.
<internationalPrice currency="EUR">423.46</internationPrice> |
purchase order schema는 USPrice element를 처음에 선언한다고 하자
<xsd:element name="USPrice" type="decimal"/> |
자 이제 여기에 어떻게 attribute를 추가할 것인가? 전에 이야기 한 것 처럼 simple type은 attribute를 가질 수 없다. 그리고 위의 예에서 decimal은 simple type이다. 따라서 attribute를 추가하기 위해서는 complex type을 정의해야 한다. 또한 element가 갖는 값이 decimal 이길 원한다고 하자. 우리의 질문을 정리하여 보면: 어떻게 simple type decimal을 기반으로 하여 complex type을 정의할 것 인가? 이고 그 답은 simple type decimal로부터 새로운 complex type을 유도하는 것이다.
|
Deriving a Complex Type from a Simple Type |
<xsd:element name="internationalPrice">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:decimal">
<xsd:attribute name="currency" type="xsd:string"/>
</xsd:extension>
<xsd:simpleContent>
</xsd:complexType>
</xsd:element>
|
우리는 새로운 element를 정의하기 위해 complex type element를 이용한다. 새로운 type의 content model은 문자만 포함하고 다른 어떤 element도 포함하지 않는다. 따라서 우리는 simpleContent element를 사용한다. 마지막으로 simple decimal type을 확장함으로서 새로운 type을 유도했다. 여기서 extension element는 simple type을 기반으로 속성을 추가할 때 사용하는 element가 되겠다.
2.5.2 Mixed Content
purchase order schema의 생성은 subelement를 포함하는 element, 그리고 문자 데이터를 포함하는 가장 하부단계의 subelement 로 특징지을 수 있다. XML schema는 또한 subelement와 나란히 나타날 수 있는 문자 데이터 그리고 가장 하부단계로 한정되지 않은 문자데이터를 갖는 스키마 생성에도 사용될 수 있다. 예를 들어 purchase order에서 나타나는 몇 개의 element를 이용하는 고객 편지의 일부를 고려해 보자
|
Snippet of Customer Letter |
<letterBody> <salutation>Dear Mr.<name>Robert Smith</name>.</salutation> Your order of <quantity>1</quantity> <productName>Baby Monitor</productName> shipped from our warehouse on <shipDate>1999-05-21</shipDate>. .... </letterBody> |
보는 바와 같이 element와 그것의 자식 element 사이에 문자들이 있다. 구체적으로 문자들은 element salutation, quantity, productName, shipDate사이에 존재한다. 그리고 letterbody의 자식의 자식 element인 name element 주위에 나타난다. 다음과 같은 schema의 일부는 letterbody를 선언한다.
|
Snippet of Schema for Customer Letter |
<xsd:element name="letterBody">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="salutation">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="quantity" type="xsd:positiveInteger"/>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
<!-- etc. -->
</xsd:sequence>
</xsd:complexType>
</xsd:element>
|
고객 편지에서 나타나는 element들이 선언되었고 우리가 전에 살펴보았던 element 와 ComplexType element를 이용하여 정의되어졌다. 문자들이 letterbody의 element 사이에 나타나도록 mixed attribute의 값이 true로 설정되어 있다.
주의할 것은 XML Schema에서의 mixed model과 XML 1.0에서의 mixed model과는 큰 차이가 존재한다는 것이다. XML schema mixed model에서는 XML 문서에서 나타나는 나타나는 child element의 수와 순서가 XML schema model에서 나타나는 child element의 수와 순서에 일치해야 한다. 이에 반해 XML 1.0 mixed model에서는 XML 문서에 나타나는 child element의 수와 순서를 제한할 수 없다. 요약하면 XML 1.0 mixed model이 부분적인 유효성 검증을 하는데 비해 XML schema는 mixed model에 대한 완전한 유효성 검증을 가능케 한다.
2.5.3 Empty Content
위에서 본 internationalPrice element는 화폐단위를 attribute로 갖었고 그 값을 content로 가졌었다. 자 이제 이 둘 모두를 attribute 값에 넣어보자.
<internationalPrice currency="EUR" value="423.46"/> |
위와 같이 표현하면 element는 어떠한 content도 포함하지 않는다. content가 비어있는 type(Empty Content)을 정의하기 위하여 우리는 content안에 element만 허용할 뿐 어떤 element도 사살상 선언하지 않는다.
|
An Empty Complex Type |
<xsd:element name="internationalPrice">
<xsd:complexType>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:attribute name="currency" type="xsd:string"/>
<xsd:attribute name="value" type="xsd:decimal"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
|
이 예에서 우리는 complexContent를 갖는 type을 정의한다. complexContent element는 complex type을 제한하고 확장하기 위해 사용한다. 그리고 anyType을 base로 갖는 restriction element는 두 개의 attribute를 선언하지만 어떤 element content도 선언하지 않는다.
다음과 같이 좀더 짧게 표현하는 것도 가능하다.
|
Shorthand for an Empty Complex Type |
<xsd:element name="internationalPrice">
<xsd:complexType>
<xsd:attribute name="currency" type="xsd:string"/>
<xsd:attribute name="value" type="xsd:decimal"/>
</xsd:complexType>
</xsd:element>
|
위와 같이 짧게 표현할 수 있는 이유는 simpleContent 또는 complexContent없이 정의된 complex type이 anyType을 제한하는 complex content로 이해되기 때문이다.
2.5.4 anyType
anyType은 그것의 content에 어떤 형이 오든 제한하지 않는다. 다음 예처럼 anyType을 이용하는 것이 가능하다.
<xsd:element name="anything" type="xsd:anyType"/> |
이러한 식으로 선언된 element의 content는 제약이 없다. 그래서 어떤 형이든 올 수가 있다. 사실상 anyType은 아무것도 구체적으로 지정되지 않으면 default값으로 사용되어 진다. 그래서 위의 예는 다음과 같이 다시 쓰일 수 있다.
<xsd:element name="anything" /> |
2.6 Annotations(주석)
XML Schema는 사람과 application 모두의 편의를 위해 주석을 3가지 형태의 element로 제공하고 있다. purchase order schema에 있어 우리는 기본적인 schema 기술과 copyright정보를 documentation element에 넣었다. xml:lang attribute는 사용하는 언어를 표시하기 위해 사용한다. 그리고 그것은 사람이 읽을 수 있는 자료가 된다. purchase order schema에서 이용되지는 않았지만 appInfo element는 tools, applications, stylesheet를 위한 정보를 제공해주는데 사용될 수 있다. appInfo를 이용한 재미있는 예제는 XML Schema Part2: Datatypes에서 simple type을 기술하는 schema이다. 어떤 facet들이 특정 simple type에 이용가능한가와 같은 이러한 schema를 기술하는 정보는 appInfo element안에 나타난다. 그리고 이러한 정보는 XML Schema Part 2 문서를 위해 자동적으로 문서를 작성하기 위해 어떤 application에서 사용된다.
documentation 과 appInfo 모두 annotation element의 subelement로 나타나지만 그것들은 대부분의 schema 생성문서의 처음에 나타날 것이다. 이것을 설명하기 위해 다음과 같은 예제는 element 선언과 complex type definition의 처음 부분에 annotation element가 나타나는 것을 보여주고 있다.
|
Annotations in Element Declaration & Complex Type Definiton |
<xsd:element name="internationalPrice">
<xsd:annotation>
<xsd:documentation xml:lang="en">
element declared with anonymous type
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:annotation>
<xsd:documentation xml:lang="en">
empty anonymous type with 2 attributes
</xsd:documentation>
</xsd:annotation>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:attribute name="currency" type="xsd:string"/>
<xsd:attribute name="value" type="xsd:decimal"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
|
2.7 Building Content Models
purchase order schema에서 complex type의 정의는 instance 문서(XML 문서)에서 나타나야 하는 element들의 순서를 모두 선언해야 한다. 그리고 element들의 occurence들도 minOccurs, masOccurs attribute를 통해 정의되어야 한다. XML Schema는 또한 content model에 나타나는 element 그룹에 제약을 줄 수 있는 방법을 제공하고 있다. 이러한 제약은 XML 1.0에서 사용가능한 제약에 몇 개의 추가적인 제약을 더한 것이다. 주의할 것은 이러한 제약들이 attribute에는 적용되지 않는다는 것이다.
XML Schema는 정의된 element들을 그룹으로 묶는 것을 가능하게 해준다. 이것을 설명하기 위해 우리는 두 개의 그룹을 소개한다.
|
Nested Choice and Sequence Groups |
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:choice>
<xsd:group ref="shipAndBill"/>
<xsd:element name="singleUSAddress" type="USAddress"/>
</xsd:choice>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:group name="shipAndBill">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
</xsd:sequence>
</xsd:group>
|
choice 그룹은 XML 문서에 나타나는 자식 element중 하나를 선택하게 만든다. 하나의 자식 element는 shipTo, billTo라는 이름의 element로 구성된 shipAndBill이라 불리는 그룹을 참조하는 그룹 element이고 다른 자식 element는 singleUSAddress이다. 따라서 XML 문서에서 purchase order element는 shipTo element, billTo element, singleUSAddress element 중 하나를 가져야 한다. 그리고 choice 그룹과 comment element, items element는 sequence 그룹의 자식들이다. XML문서에서 sequence 그룹에 정의 되어진대로 순서대로 표시되어야 한다. 그룹에서의 element를 제약하는 세 번째 옵션이 존재한다. 그룹에 속하는 모든 element는 한번 나타나거나 한번도 나타나지 말아야 하며 어떤 순으로 나타나도 상관은 없다. all 그룹은 이러한 경우에 사용된다. all 그룹에는 element들만 포함되어야 하며 어떤 그룹도 올 수 없다. 게다가 어떤 element도 한번 이상 나타나서는 안된다. 즉 minOccurs와 maxOccurs에 사용가능한 값은 0과 1이다. 예를 들어 purchaseOrder의 자식 element가 어떤 순으로 나타나게 해야 한다면 우리는 다음과 같이 정의해 줄 수 있다.
|
An "All" Group |
<xsd:complexType name="PurchaseOrderType">
<xsd:all>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:all>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
|
이 정의에 의하면 purchaseOrder에서 comment element는 나타날 수도 있고 나타나지 않을 수도 있으며 shipTo, billTo, items element의 앞,뒤에 위치할 수 있지만 반드시 한번만 나타나야 한다. 게다가 all 그룹의 규정상 comment와 같은 element가 all 그룹밖에 선언될 수 없다. 다음과 같은 것은 잘못된 예를 보여주고 있다.
|
Illegal Example with an 'All' Group |
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:all>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element name="items" type="Items"/>
</xsd:all>
<xsd:sequence>
<xsd:element ref="comment" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
|
2.8 Attribute Groups
우리가 purchase order의 각각의 item에 관한 더 많은 정보를 제공하기를 원한다고 하자(예를 들어 각각의 아이템에 대한 무게와 원하는 배송방법과 같은 것) 우리는 item element type 선언에 weightKg과 shipBy attribute 선언을 추가하여 이것을 가능하게 할 수 있다.
|
Adding Attributes to the Inline Type Definition |
<xsd:element name="Item" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence> <xsd:attribute name="partNum" type="SKU" use="required"/>
<!-- add weightKg and shipBy attributes -->
<xsd:attribute name="weightKg" type="xsd:decimal"/>
<xsd:attribute name="shipBy">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="air"/>
<xsd:enumeration value="land"/>
<xsd:enumeration value="any"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
|
대안으로 우리는 item element의 모든 바라는 속성을 포함하는 어떤 이름을 가진 attirbute 그룹을 생성할 수 있다. 그리고 item element에 선언된 이름으로 이 그룹을 참조할 수 있다.
|
Adding Attributes Using an Attribute Group |
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<!-- attributeGroup replaces individual declarations -->
<xsd:attributeGroup ref="ItemDelivery"/>
</xsd:complexType>
</xsd:element>
<xsd:attributeGroup name="ItemDelivery">
<xsd:attribute name="partNum" type="SKU" use="required"/>
<xsd:attribute name="weightKg" type="xsd:decimal"/>
<xsd:attribute name="shipBy">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="air"/>
<xsd:enumeration value="land"/>
<xsd:enumeration value="any"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:attributeGroup>
|
이런 식으로 attribute 그룹을 이용함으로서 schema의 가독성을 향상시킬 수 있고 schema를 쉽게 업데이트 할 수 있다.(attribute 그룹이 다른 장소에서 만들어지고 편집되기 때문에 이것을 참조하는 많은 선언과 독립적으로 쉽게 업데이트 할 수 있다.) 주의할 점은 attribute 그룹이 다른 attribute 그룹을 포함할 수 있다는 것이다. 또 하나 주의할 점은 attribute 그룹 선언과 attribute 그룹 참조는 complex type 정의의 맨 끝에 와야 한다는 것이다.
2.9 Nil Values
po.xml에 나열된 purchase order item들 중 Lawnmower는 어떤 shipDate element도 포함하지 않는다. 아마 우리 시나리오에 있어 그러한 XML 문서작성자의 의도적인 실수는 아마도 아이템들이 아직 선적되지 않았음을 나타내고자 함이다. 그리나 일반적으로 element가 없다고 해서 어떤 특정의미를 갖는 것은 아니다. 즉 정보가 없거나 이용가능하지 않거나 그 element가 아마 다른 이유 때문에 없을 것으로 판단된다. 때때로 선적되지 않은 아이템, 알려지지 않은 정보,적용할 수 없는 정보등을 element에 명백히 표현하는 것이 바람직할 때가 있다. 즉 관계형 데이터베이스에서 사용되는 null값처럼 사용하고 싶은 것이다. XML schema에서는 nil 값이 이것을 가능하게 만들어 준다. 사실 nil 값을 표현해주는 element는 존재하지 않는다. 이것을 우리는 attribute를 이용해 표현한다.
다음과 같이 우리는 shipDate element를 nil 값을 갖는 것으로 표현할 수 있다.
<shipDate xsi:nil="true"></shipDate> |
nil attribute는 instance를 위한 XML Schema namespace(http://www.w3c.org/2001/XMLSchema-instance)의 일부분으로 정의되어져 있다.
浙公网安备 33010602011771号