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의 숫자여야 한다는 것을 나타냅니다.