مثال على 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 بتحقق من هذا المستند بناءً على某个 schema. السطر التالي: xsi:noNamespaceSchemaLocation="shiporder.xsd" يحدد موقع schema (في هذا السياق، يقع في نفس المجلد مع "shiporder.xml").

إنشاء XML Schema

الآن، نحتاج إلى إنشاء نموذج لـ XML هذا الملف.

يمكننا البدء بفتح ملف جديد، وتمييزه باسم "shiporder.xsd". لإنشاء النموذج، نحتاج فقط إلى اتباع بنية وثيقة XML، وتعريف كل عنصر نكتشفه.

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
...
</xs:schema>

في النموذج أعلاه، استخدمنا النطاق القياسي (xs)، وال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) مسبقًا من قبل مقدم النطاق، هذا النطاق مرتبط بنموذج XML schema المحدد للأنواع البيانية المسبقة (predefined schema data types):

<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" بالظهور بقدر ما يرغب الخالق في الظهور.

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

استخدام الأنواع المحددة (الأنواع المسمى)

تعريف الطريقة الثالثة للتصميم كائنات أو أنواع، مما يمنحنا القدرة على إعادة استخدام تعريف العناصر. الطريقة هي: أولاً، تسمية العناصر البسيطة والمركبة، ثم إشارة إلى العناصر من خلال خاصية type.

هذا هو ملف النمذجة باستخدام الطريقة الثالثة ("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.