공간정보/표준

XML Schema Tutorial

하늘이푸른오늘 2017. 12. 24. 14:29

XML Schema란?

  • XML Schema는 XML 문서의 구조를 설명함.
  • XML Schema 언어는 XSD(XML Schema Definition) 이라고도 한다.
  • XML 스키마의 목적 : XML 문서의 합법적 기본구성요소를 정의
    • 문서에 어떤 요소와 속성이 나타나야 하는가?
    • 하위 요소들의 수와 순서
    • 요소와 속성의 데이터 유형
    • 요소와 속성의 기본값/고정값
  • 왜 XML 스키마를 배워야 하는가?
    • 이미 수백가지의 표준화된 XML 포맷이 사용중이다.
    • 수많은 XML 표준은 XML Schema로 정의되어 있다.
    • XML Schema는 XML기반이며, DTD를 대체할 수있으며 훨씬 강력하다.
  • XML 스키마는 데이터유형을 지원한다.
    • 허용되는 내용을 쉽게 설명가능
    • 데이터의 정확성 검증가능
    • 데이터에 대한 제한을 정의가능
    • 데이터 패턴(포맷)을 쉽게 정의가능
    • 다른 유형으로 쉽게 변환 가능
  • XML Schema는 XML 문법을 사용함. 따라서
    • 새로운 언어를 배울 필요 없으며
    • XML 에디터로 스키마파일을 편집할 수 있고
    • XML parser로 스키마파일을 파싱할 수 있고
    • XML DOM으로 처리할 수 있으며
    • XSLT로 스키마를 변환할 수 있다.
    • XML Schema는 확장가능하다. 따라서
      • 다른 스키마를 재사용가능하다.
      • 표준 유형에서 새로운 데이터유형을 생성할 수 있다.
      • 동일한 문서에서 여러개의 스키마를 참조할 수 있다.
  • XML 스키마를 사용하면 안전한 데이터 통신이 가능하다.
    • 데이터를 보낼때, 내용에 대한 동일한 이해가 가능하다.
    • 수신자가 이해할 수 있는 방법으로 데이터를 설명할 수 있다.
    • "3-11-2004" 와 같이 데이터 해석이 달라질 염려를 없앨 수 있다.
  • Well-Formed 문서만으로는 부족하다.
    • Well-Formed 된 문서도 오류가 있을 수 있다.
    • XML Schema를 사용하면 에러를 검증할 수 있다.

XSD 사용법

  • XML 문서는 XML Schema에 대한 참조를 가질 수 있다.
  • 예제 XML 문서 : note.xml

<?xml version="1.0" encoding="utf-8"?>
<note>
    <to>Tove</to>
    <from>Jani</from>
    <body>Don't forget me this weekend!</body>
</note>

  • 이 문서에 대한 XML Schema : note.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="https://www.w3schools.com"
    xmlns="https://www.w3cschools.com"
    elementFormDefault="qualified">

<xs:element name="note">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="to" type="xs:string" />
            <xs:element name="from" type="xs:string" />
            <xs:element name="body" type="xs:string" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

</xs:schema>

  • 이 note.xsd를 참조하여 note.xml을 다시 작성하면

<?xml version="1.0"? encoding="utf-8">
<note 
xmlns="https://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.w3schools.com/xml/note.xsd">
    <to>Tove</to>
    <from>Jani</Jani>
    <body>Don't forget me this weekend!</body>
</note>

XSD- <schema> 요소

  • <schema> 요소는 모든 XML Schema 문서의 root 요소이다.
  • <schema> 요소는 속성을 가질 수 있다.
    • xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      • 이 schema에 사용되는 데이터유형이 w3.org 네임스페이스에서 왔음을 의미함
      • 이 데이터유형들을 사용할 때 xs: 를 사용해야 함
    • targetNamespace="https://w3schools.com"
      • 이 스키마에서 정의되는 요소(note, to, body)는 "w3school" 네임스페이스에서 왔음
    • xmlns="https://www.w3schools.com"
      • 네임스페이스 기본값이 "https://www.w3schools.com" 임
    • elementFormDefault="qualified"
      • 이 스키마에서 선언되는 XML 인스턴스 문서에 사용되는 모든 요소는 네임스페이스에 한정되어야 한다(namespace qualified)
  • XML 문서에서 스키마를 참조할 때...
    • xmlns="https://www.w3schools.com"
      • 기본 네임스페이스 선언. 이 문서에서 사용된 모든 요소들은 w3schools 네임스페이스에 선언되었음을 의미함
    • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      • 먼저 이렇게 XML schema instance 네임스페이스를 가져오면, 아래의 schemaLocation 속성을 사용할 수 있게됨.
    • xsi:schemaLocation="https://www.w3schools.com note.xsd"
      • schemaLocation 속성은 두개의 값이 들어가며, 첫번째값은 사용할 네임스페이스, 두번째는 해당 네임스페이스에서 사용하고자하는 XML 스키마의 위치임.

XSD Simple 요소

  • simple 요소는 텍스트만 담을 수 있는 요소. 
    • 하지만, 텍스트는 여러가지 유형이 있음. XML Schema definition에는 boolean, string, data 등의 유형이 정의되어 있고, 사용자가 정의할 수도 있다.
    • 내용을 제한하기 위해 데이터유형에 제한(facets)를 걸 수도 있고, 특정한 패턴만 요구할 수도 있음
  • Simple 요소 정의방법
    • <xs:element name="xxx" type="yyy" />
      • xxx는 이름. 
      • yyy는 다음과 같은 여러가지를 사용할 수 있음
        • xs:string
        • xs:decimal
        • xs:integer
        • xs:boolean
        • xs:date
        • xs:time
  • 예제 xml 요소

<lastname>Heo</lastname>
<age>35</age>
<dateborn>1970-03-27</dateborn>

  • 이에 대한 simple 요소 정의

<xs:element name="lastname" type="xs:string"/>
<xs:element name="age" type="xs:integer"/>
<xs:element name="dateborn" type="xs:date"/>

  • 기본값(default)과 고정값(fixed)
    • 기본값
      • <xs:element name="color" type="xs:string" default="red">
    • 고정값
      • <xs:element name="Rcolor" type="xs:string" fixed="red">

XSD 속성

  • 속성을 정의하는 방법
    • <attribute name="xxx" type="yyy" />
    • 여기서 "yyy" 데이터 유형은 element와 동일
    • <lastname lang="EN">Smith</lastname>을 정의하려면

<xs:element name="lastname" type="xs:string" />
<xs:attribute name="lang" type="xs:string" />

  • 기본값과 고정값을 부여하는 방법은 요소의 경우와 동일하다.
  • 필수/선택은 "use" attribute를 사용한다.
    • <xs:attribute name="lang" type="xs:string" use="required" />

XSD Restrictions

  • 이상과 같이 type을 지정하면 들어올 수 있는 내용을 제한하게 된다.
  • 여기에 사용자가 원하는 제한을 더 가할 수 있다. 이것을 facets라고 한다.
  • 최대값 최소값 : 아래의 예는 값의 범위를 정하는 방법

<xs:element name="age">
    <xs:simpleType>
        <xs:restriction base="xs:integer">
            <xs:minInclusive value="0" />
            <xs:maxInclusive value="120" />
        </xs:restriction>
    </xs:simpleType>
</xs:element>

  • 값 목록을 지정할 경우

<xs:element name="car">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:enumeration value="Audi" />
            <xs:enumeration value="BMV" />
            <xs:enumeration value="Golf" />
        </xs:restriction>
    </xs:simpleType>
</xs:element>

  • 아래는 위와 동등한 내용
    • 이 경우, "carType"은 다른 항목에도 사용할 수 있다.
    • 재활용이 가능하므로, 대부분 이런 형태로 정의한다.

<xs:element name="car" type="carType" />

<xs:simpleType name="carType">
    <xs:restriction base="xs:string">
        <xs:enumeration value="Audi" />
        .........
</xs:simpleType>

  • 기타 여러가지 제한
    • <xs:pattern value="[a-z]" />    : 소문자로 한글자.
    • <xs:pattern value="[A-Z][A-Z][A-Z]" /> : 대문자로 세글자
    • <xs:pattern value="[a-zA-A][a-zA-A][a-zA-A]" />: 세글자
    • <xs:pattern value="[xyz]" />            : "x" 또는 "y" 또는 "z"
    • <xs:pattern value="[0-9][0-9][0-9][0-9][0-9]" />        : 5자리 숫자
    • <xs:pattern value="([a-z])*" />        : 소문자만. 글자수는 0 이상
    • <xs:pattern value="([a-z][A-Z])+" /> : 소문자+대문자쌍으로. 글자수는 2이상
    • <xs:pattern value="male|female" /> : "male" 또는 "female" 만
    • <xs:pattern value="[a-zA-Z0-9]{8}" />    : 영숫자 8글자
    • <xs:whiteSpace value="preserve" />      : 공백문자(LF, CR, Tab등)을 그대로 유지
    • <xs:whiteSpace value="replace" />        : 모든 종류의 공백문자들을 space로 바꿈
    • <xs:whiteSpace value="collapse" />       : 앞뒤, 여러개의 공백을 하나의 space로
    • <xs:length value="8" />                      : 8글자
    • <xs:minLength value="5" /> <xs:maxLength value="8" />   5글자에서 8글자까지
  • 기타 데이터 유형에 관한 제한
    • enumeration : 허용되는 값의 목록을 정의함
    • factionDigits : 소숫점이하 자릿수 지정(0 이상)
    • length : 문자의 수 또는 목록의 경우 목록의 수(0 이상)
    • maxExclusive : 허용되는 숫자형의 상한값(미만)
    • maxInclusive : 허용되는 숫자형의 상한값(이하)
    • maxLength : 최대 문자수 또는 최대 목록수
    • minExclusive : 허용되는 숫자형의 하한값(초과)
    • minInclusive : 허용되는 숫자형의 하한값(이상)
    • minLength : 최소 문자수 또는 최소 목록수
    • pattern : 허용되는 문자열의 순서
    • totalDigits : 허용되는 숫자 자릿수 (0 이상)
    • whiteSpace : white space(LF, tab, space, CR)를 어떻게 취급할 지 지정

XSD Complex 요소

  • Complex 요소란 다른 요소나 속성을 포함하는 요소로 4가지 종류가 있다.
    • <product pid="12354" />                                  : empty 요소
    • <employee><fn>A</fn><ln>B</ln></employee>  : 다른 요소만 포함하는 요소
    • <food type="desert">Ice cream</food>               : 텍스트만 포함하는 요소
    • <desc>It happened on <date lang="NR">03.03.99</date></desc>
                                          : 다른 요소와 텍스트를 포함하는 요소
    • 단!!!! 각각의 요소는 속성을 가질 수 있다.

Complex 요소를 정의하는 방법의 예

<employee>
    <firstname>Jorhn</firstname>
    <lastname>Smith</lastname>
</employee>

====

<xs:element name="employee">
    <xs:complexType>
        <xs:sequence>                    sequence를 사용하면 순서대로 나타나야 함.
            <xs:element name="firstname" type="xs:string" />
            <xs:element name="lastname" type="xs:string" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

  • 유형을 따로 정하면 여러번 반복하여 사용할 수 있다.

<xs:element name="employee" type="personType" />
<xs:element name="student" type="personType" />

<xs:complexType name="personType">
    <xs:sequence>
        <xs:element name="firstname" type="xs:string" />
        
<xs:element name="lastname" type="xs:string" />
    </xs:sequence>
<xs:complexType>

  • xs:complexContent와 xs:extension을 사용하면 기본 complex 요소를 확장시킬 수 있다.

<xs:element name="employee" type="fullPersonInfo" />

<xs:complexType name="personinfo">
    <xs:sequence>
        <xs:element name="firstname" type="xs:string" />
        
<xs:element name="lastname" type="xs:string" />
    </xs:sequence>
<xs:complexType>

<xs:complexType name="fullPersonInfo">
    <xs:complexContent>
        <xs:extension base="personinfo">
            <xs:sequence>
                <xs:element name="address" type="xs:string">
                
<xs:element name="city" type="xs:string">
                <xs:element name="country" type="xs:string">
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

XSD Empty 요소

  • <product prodid="1234" /> 와 같이 내용이 없는 요소를 정의하려면 아래의 방법이 가장 간단.

<xs:element name="product" type="prodType" />

<xs:complexType name="prodtype">
    <xs:attribute name="prodid" type="xs:positiveInteger" />
</xs:complexType>

XSD 요소들만 들어가는 Complex 유형

<person>
    <firstname>A</firstname>
    <lastname>B</lastname>
</person>

====

<xs:element name="person" type="personType" />

<xs:complexType name="personType">
    <xs:sequence>
        <xs:element name="firstname" type="xs:string" />
        <xs:element name="lastname" type="xs:string" />
    </xs:sequence>
</xs:complexType>

Text만 들어가는 Complex 유형

  • simple 유형은 <xs:element name="xxx" type="yyy"/> 와 같이, 제한도, 속성도 못넣음
  • <shoesize country="france">35</shoesize> 를 정의하는 방법
    • complexType으로 정의하고, 내부에 simpleContent를 넣고 그 안에 extension 또는 restriction을 사용함.

<xs:element name="shoesize" type="shoeType" />

<xs:complexType name="shoeType"
    <xs:simpleContent>
        <xs:extension base="xs:integer">
            <xs:attribute name="country" type="xs:string" />
        </xs:extension>
    </xs:simpleContent>
</xs:complexContent

XSD 문자와 요소가 혼합된 Comlex 유형

  • 아래와 같이 문자와 요소가 섞여도 무방한 Complex 유형을 만들려면 mixed="true"를 추가하면 된다.

<letter>
    Dear Mr.<name>John Smith</name>.
    Your order <orderid>2043</orderid>
    will be shipped on <shipdate>2001-07-13</shipdate>.
</letter>

<xs:element name="letter" type="letterType" />

<xs:complexType name="letterType" mixed="true">
    <xs:sequence>                                        ----> 순서대로 나타나야 함
        <xs:element name="name" type="xs:string">
        <xs:element name="order" type="xs:positiveInteger">
        <xs:element name="shipdate" type="xs:date">
    </xs:sequence>
</xs:complexType>

XSD 지시자(Indicator)

  • 순서 지시자(Order Indicator)
    • sequence - 모두 한번씩. 정해진 순서대로
    • all - 모두 단 한번씩 등장해야 함. 순서는 없음
    • choice - 둘중의 하나만 등장
  • 횟수 지시자(Occurence Indicator)
    • minOccurs/maxOccurs
  • 그룹 지시자(Group Indicator)
    • <xs:group name="xxx">   
    • 그룹을 지정하면 다른 정의에서도 사용할 수 있음
  • 속성 그룹(attribute Group)
    • <xs:attributeGroup name="xxx">
    • 그룹을 지정하면 다른 정의에서도 사용할 수 있음
  • 예제

<?xml version="1.0" encoding="UTF-8" ?>
<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="family.xsd">

<person>
    <fullname>Min Heo</fullname>
    <childname>Minho</childname>
</person>

<person>
    <fullname>Tove Refsnes</fullname>
    <childname>Hege</childname>
    <childname>Stale</childname>
    <childname>Jim</childname>
</person>

<person>
    <fullname>Stale Refsnes</fullname>
</person>

</persons>

  • family.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
      elementFormDefault="qualified">

<xs:element name="persons">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="person" maxOccurs="unbounded">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="fullname" type="xs:string"/>
            <xs:element name="childname" type="xs:string"
                  minOccurs="0" maxOccurs="5"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:element>

</xs:schema>

XSD <any> 요소, <anyAttribute> 요소

  • <any> 요소를 사용하면 스키마에서 지정하지 않은 요소를 사용할 수 있도록 확장시킬 수 있다.
  • 아래는 family.xsd 파일의 일부

<xs:element name="person">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="firstname" type="xs:string" />
            <xs:element name="lastname" type="xs:string" />
            <xs:any minOccurs="0" />
 --- </xs:element>

  • 사용법은....

XSD Substitution Group

  • 예를 들어, 영국고객과 노르웨이고객이 있어서, 영국식/노르웨이 언어로 정의하도록
  • head 요소를 정의한 후, 이 head 요소를 대체할 수 있다고 명시한 또 다른 요소를 정의한다. 
  • 아래에서 head 요소는 "name", "navn"요소는 "name" 요소를 대체할 수 있음.

<xs:element name="name" type="xs:string" />
<xs:element name="navn" substitutionGroup="name" />

  • XML Schema

<xs:element name="name" type="xs:string" />
<xs:element name="navn" substitutionGroup="name" />

<xs:complexType name="customerType">
    <xs:sequence>
        <xs:element ref="name" />
    <xs:sequence>
</xs:complexType>

<xs:element name="customer" type="customerType" />
<xs:element name="kunde" substitutionGroup="customer" />

  • 이런 식으로 정의하였을 때 XML 파일에는 아래와 같이 두가지가 모두 들어갈 수 있다.

<customer>
    <name>Min Heo</name>
</customer>
<kunde>
    <navn>John Smith</navn>
</kunde>

  • 대체를 금지시키고 싶으면 block을 사용하면 된다.

<xs:element name="name" type="xs:string" block= "substitution" />

  • SubstitutionGroup 사용방법
    • 대체가능 요소(substitutable element)는 head요소와 동일한 type 또는 head 요소 유형에서 유도된 유형이어야 한다.
    • 동일한 유형일 경우엔 substitution 하면서 type은 정의할 필요없지만, 유도할 경우 새로 정의
    • substitutionGroup의 모든 요소(head 요소 및 substitutable 요소)는 반드시 Global 요소로 선언

XSD 예제

<?xml version="1.0" encoding="UTF-8" ?>
<shiporder orderid="8893"
    xmlns:xsi="http://www.w3c.org/2001/XMLSchema-Instance"
    xsi:noNamespaceSchemaLocaiton="shiporder.xsd">

    <orderperson>John Smith</orderperson>
    <shipto>
        <name>Ola Nordmann</name>
<address>Langgt 2</address>
<city>400 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>

  • root 요소 : shiporder (orderid라는 속성이 있음)
    shiporder는 3개의 child 요소(orderperson, shipto, item)
  • xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance"- 반드시 schema에 비교해야 함을 의미
  • xsi:noNamespaceSchemaLocation="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>

XSD 분할

  • 문서가 복잡해지면 읽기 힘들다.
  • 모든 요소와 속성을 미리 다 정의한 후, 이들을 ref 속성을 사용하여 참조한다. 

Named 유형을 사용하기

  • 클래스/유형을 먼저 정의하고, 요소 정의를 재활용. 


===

원문 : https://www.w3schools.com/xml/schema_intro.asp 에서...