یک نمونه 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 شامل عنصر ریشه "shiporder" است که شامل ویژگی ضروری به نام "orderid" است. عنصر "shiporder" شامل سه عنصر مختلف است: "orderperson"، "shipto" و "item". عنصر "item" دو بار ظاهر می‌شود و شامل یک "title"، یک عنصر اختیاری "note"، یک "quantity" و یک عنصر "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>

در schema بالا، ما از نام‌فضای استاندارد (xs) استفاده کرده‌ایم، این نام‌فضا با Schema language definition مرتبط است، که URI استاندارد آن 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 مرتبط است که داده‌های 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" چندین بار ظاهر شود. این از طریق تنظیم مقدار 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"/>

این فایل schema است که به نام "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 برای ارجاع به آنها استوار است.

این فایل 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>

از نوع‌های مشخص شده (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>

عنصر محدودی نشان‌دهنده نوع داده‌ای است که از فضای نام نوع داده‌های شماره‌نویسی‌شده W3C XML Schema منشاء دارد. بنابراین، بخش زیر نیز به این معنی است که مقدار عنصر یا ویژگی باید مقدار نوع رشته‌ای باشد:

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

عنصر محدودیت معمولاً برای اعمال محدودیت بر عناصر استفاده می‌شود. به این بخش‌های از schema فوق اشاره می‌کنیم:

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

این کد نشان می‌دهد که ارزش عنصر یا ویژگی باید رشته‌ای باشد و باید شش کاراکتر پیاپی باشد و این کاراکترها باید اعداد 0-9 باشند.