XSD의 예
이 장에서는 XML 스키마를 작성하는 방법을 보여줍니다. 또한 스키마가 다양한 방식으로 작성될 수 있음을 배우게 됩니다.
XML 문서
"shiporder.xml"이라는 XML 문서를 살펴보겠습니다.
<?xml version="1.0" encoding="UTF-8"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>
위의 XML 문서는 "orderid"라는 필수 속성을 포함하는 루트 요소인 "shiporder"로 구성됩니다. "shiporder" 요소에는 "orderperson", "shipto" 및 "item"의 세 가지 하위 요소가 있습니다. "item" 요소는 두 번 나타나며 "title", 선택적 "note" 요소, "quantity" 및 "price" 요소를 포함합니다.
위의 줄: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"는 XML 파서에 이 문서가 스키마에 대해 검증되어야 함을 알려줍니다. xsi:noNamespaceSchemaLocation="shiporder.xsd" 줄은 스키마가 있는 위치를 지정합니다(여기서는 "shiporder.xml"과 동일한 폴더에 있음).
XML 스키마 생성
이제 위의 XML 문서에 대한 스키마를 생성하려고 합니다.
"shiporder.xsd"라고 하는 새 파일을 여는 것으로 시작합니다. 스키마를 생성하기 위해 우리는 단순히 XML 문서의 구조를 따르고 찾은 대로 각 요소를 정의할 수 있습니다. 표준 XML 선언부터 시작하여 스키마를 정의하는 xs:schema 요소가 뒤따릅니다.
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
</xs:schema>
위의 스키마에서 표준 네임스페이스(xs)를 사용하고 이 네임스페이스와 관련된 URI는 http://www.w3.org/2001/XMLSchema의 표준 값을 갖는 스키마 언어 정의입니다.
다음으로 "shiporder" 요소를 정의해야 합니다. 이 요소에는 속성이 있고 다른 요소가 포함되어 있으므로 복합 유형으로 간주합니다. "shiporder" 요소의 자식 요소는 하위 요소의 순서가 지정된 순서를 정의하는 xs:sequence 요소로 둘러싸여 있습니다.
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
</xs:element>
그런 다음 "orderperson" 요소를 단순 유형으로 정의해야 합니다(속성이나 기타 요소가 포함되어 있지 않기 때문에). 유형(xs:string)에는 미리 정의된 스키마 데이터 유형을 나타내는 XML 스키마와 연결된 네임스페이스 접두사가 붙습니다.
<xs:element name="orderperson" type="xs:string"/>
다음으로 복합 유형인 "shipto" 및 "item"의 두 요소를 정의해야 합니다. "shipto" 요소를 정의하는 것으로 시작합니다.
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
스키마를 사용하여 maxOccurs 및 minOccurs 속성이 있는 요소에 대해 가능한 발생 수를 정의할 수 있습니다. maxOccurs는 요소의 최대 발생 횟수를 지정하고 minOccurs는 요소의 최소 발생 횟수를 지정합니다. maxOccurs 및 minOccurs 둘 다의 기본값은 1입니다!
이제 "item" 요소를 정의할 수 있습니다. 이 요소는 "shiporder" 요소 내에 여러 번 나타날 수 있습니다. 이것은 "item" 요소의 maxOccurs 속성을 "unbounded"로 설정하여 지정됩니다. 이는 작성자가 원하는 만큼 "item" 요소가 발생할 수 있음을 의미합니다. "note" 요소는 선택 사항입니다. minOccurs 속성을 0으로 설정하여 이것을 지정했습니다.
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
이제 "shiporder" 요소의 속성을 선언할 수 있습니다. 이것은 필수 속성이므로 use="required"를 지정합니다.
참고: 속성 선언은 항상 마지막에 와야 합니다.
<xs:attribute name="orderid" type="xs:string" use="required"/>
다음은 "shiporder.xsd"라는 스키마 파일의 전체 목록입니다.
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
스키마 나누기
이전의 설계 방법은 매우 간단하지만 문서가 복잡할 때 읽기 및 유지 관리가 어려울 수 있습니다.
다음 디자인 방법은 모든 요소와 속성을 먼저 정의한 다음 ref 속성을 사용하여 참조하는 것입니다.
다음은 스키마 파일("shiporder.xsd")의 새로운 디자인입니다.
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- definition of complex elements -->
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="city"/>
<xs:element ref="country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
명명된 유형 사용
세 번째 디자인 방법은 요소 정의를 재사용할 수 있는 클래스 또는 유형을 정의합니다. 이것은 simpleTypes 및 complexTypes 요소의 이름을 지정한 다음 요소의 type 속성을 통해 가리킴으로써 수행됩니다.
다음은 스키마 파일("shiporder.xsd")의 세 번째 디자인입니다.
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="stringtype">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="inttype">
<xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>
<xs:simpleType name="dectype">
<xs:restriction base="xs:decimal"/>
</xs:simpleType>
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="shiptotype">
<xs:sequence>
<xs:element name="name" type="stringtype"/>
<xs:element name="address" type="stringtype"/>
<xs:element name="city" type="stringtype"/>
<xs:element name="country" type="stringtype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemtype">
<xs:sequence>
<xs:element name="title" type="stringtype"/>
<xs:element name="note" type="stringtype" minOccurs="0"/>
<xs:element name="quantity" type="inttype"/>
<xs:element name="price" type="dectype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="shipordertype">
<xs:sequence>
<xs:element name="orderperson" type="stringtype"/>
<xs:element name="shipto" type="shiptotype"/>
<xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
</xs:sequence>
<xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>
<xs:element name="shiporder" type="shipordertype"/>
</xs:schema>
제한 요소는 데이터 유형이 W3C XML 스키마 네임스페이스 데이터 유형에서 파생되었음을 나타냅니다. 따라서 다음 조각은 요소 또는 속성의 값이 문자열 값이어야 함을 의미합니다.
<xs:restriction base="xs:string">
제한 요소는 요소에 제한을 적용하는 데 더 자주 사용됩니다. 위의 스키마에서 다음 행을 보십시오.
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
이는 요소 또는 속성의 값이 문자열이어야 하고, 한 행에 정확히 6자여야 하며, 해당 문자는 0에서 9 사이의 숫자여야 함을 나타냅니다.