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)을 사용했으며, 이 이름 공간과 관련된 URI는 Schema의 언어 정의(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)의 접두사는 이름 공간의 접두사에 의해 정의되며, 이 이름 공간은 XML 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의 숫자여야 합니다.