一個 XSD 實例

บทนี้จะแสดงให้เห็นว่าจะเขียน XML Schema ได้อย่างไร คุณยังจะเรียนรู้วิธีต่างๆ ที่จะเขียน schema

เอกสาร XML

ให้เรามองเอกสาร XML ที่มีชื่อว่า "shiporder.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 ที่กล่าวถึงนี้มี element ราก "shiporder" ซึ่งมี attribute ที่ต้องมีชื่อว่า "orderid" อยู่ ซึ่ง "shiporder" element มี element ลูกสายสามตัวคือ: "orderperson"、"shipto" และ "item" ซึ่ง "item" element ปรากฏขึ้นถึงสองครั้ง มี element "title" และ element "note" ที่เป็นอนุญาติได้ และมี element "quantity" และ element "price"

บรรทัดนี้ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" บอก XML parser ว่าต้องการตรวจสอบเอกสารนี้ตาม schema ที่กำหนด บรรทัดนี้: xsi:noNamespaceSchemaLocation="shiporder.xsd" กำหนดตำแหน่งของ schema (ที่นี้ มันอยู่ในเดียวกับ "shiporder.xml" ในไดเรกทอรีเดียวกัน)

สร้าง XML Schema

ตอนนี้ เราต้องการที่จะสร้าง schema สำหรับเอกสาร XML นี้

เราสามารถเริ่มด้วยการเปิดไฟล์ใหม่ และตั้งชื่อไฟล์ว่า "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>

ในสคีมที่ขึ้นมานี้ เราใช้ชื่อมาตรฐานของนามสเปซ (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 ที่มีการกำหนดชนิดของ data type ที่เป็นมาตรฐาน

<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" อิเล็มหลายครั้ง นี่จะทำได้โดยกำหนดค่าของ maxOccurs ของอิเล็ม "item" ให้เป็น "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="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 ในการอ้างอิงเหล่านั้น。

นี่เป็นแบบแบบไซมาชี้แบบไซมาชี้ที่ออกแบบด้วยวิธีใหม่:

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

ใช้ประเภทที่กำหนด (Named Types)

วิธีที่สามการออกแบบกำหนดประเภทหรือรูปแบบเพื่อให้เรามีความสามารถในการใช้งานประเภทหรือการกำหนดศัพท์ที่เรียกได้มาใช้ใหม่ ๆ โดยทางเลือกเป็นต้นตอนคือ การตั้งชื่อสำหรับองค์ประกอบง่ายและองค์ประกอบที่ประกอบด้วยองค์ประกอบ แล้วใช้แบบที่มีอยู่ขององค์ประกอบผ่านรายละเอียด type

นี่คือบทบัญญัติ 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 的數字。