XSD 인스턴스 하나

이 장에서는 XML Schema를 작성하는 방법을 설명합니다. 또한 Schema를 작성하는 다양한 방법을 배울 것입니다.

XML 문서

이름이 "shiporder.xml"인 XML 문서를 보겠습니다:

<?xml version="1.0" encoding="ISO-8859-1"?>
<shiporder orderid="889923">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
 <orderperson>George Bush</orderperson>
 <shipto>
  <name>John Adams</name>
  <address>Oxford Street</address>
  <city>London</city>
  <country>UK</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 문서는 "shiporder" 루트 요소를 포함하고 있으며, "orderid"라는 이름의 속성이 필요합니다. "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 Schema를 생성하세요

지금, 위의 XML 문서에 schema를 생성해야 합니다.

새 파일을 열고 "shiporder.xsd"라는 이름을 지정할 수 있습니다. schema를 생성하려면 단순히 XML 문서의 구조를 따라 우리가 발견한 각 요소를 정의하는 것만으로 충분합니다. 먼저, 표준 XML 선언을 시작합니다:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
...
</xs:schema>

위의 schema에서는 표준 이름 공간 (xs)을 사용했으며, 이 이름 공간은 Schema의 언어 정의와 연결되어 있습니다. 이 이름 공간의 URI는 Schema language definition의 표준 값인 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)의 접두사는 이름 공간의 접두사에 의해 정의되며, 이 이름 공간은 사전 정의된 schema 데이터 타입과 관련된 XML schema와 연결됩니다:

<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>

schema를 통해 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"라는 이름의 schema 파일의 문서 목록입니다:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<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>

Schema 분할

이전 설계 방법은 매우 간단하지만, 문서가 복잡해지면 읽기와 유지보수가 어려워집니다.

다음에 소개할 설계 방법은 모든 요소와 속성의 정의를 먼저하고 그 다음에 ref 속성을 사용하여 참조하는 방법에 기반합니다.

이는 새로운 방법으로 설계된 schema 파일입니다:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- 간단 요소 정의 -->
<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"/>
<!-- 속성 정의 -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- 복합 요소 정의 -->
<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>

지정된 타입(이름 지정 타입) 사용

제3가지 설계 방법은 클래스나 타입을 정의하며, 이를 통해 요소 정의를 반복적으로 사용할 수 있게 합니다. 구체적인 방법은 다음과 같습니다: 먼저 간단 요소와 복합 요소에 이름을 부여한 후, 요소의 type 속성을 통해 그들을 지정합니다.

이는 제3가지 방법을 통해 설계된 schema 파일("shiporder.xsd")입니다:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<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>

restriction 요소는 데이터 타입이 W3C XML Schema 명명 공간의 데이터 타입에서 비롯되었음을 보여줍니다. 따라서 다음 부분은 요소나 속성의 값이 문자형 값이어야 한다는 의미입니다:

<xs:restriction base="xs:string">

restriction 요소는 요소에 제한을 가르키는 데 사용됩니다. 다음은 이 schema에서 가져온 부분입니다:

<xs:simpleType name="orderidtype">
 <xs:restriction base="xs:string">
  <xs:pattern value="[0-9]{6}"/>
 </xs:restriction>
</xs:simpleType>

이 코드는 요소나 속성의 값이 문자열이어야 하며, 연속된 여섯 개의 문자이어야 하며, 이 문자들은 0-9의 숫자여야 한다는 것을 나타냅니다.