Cấu trúc Gốc và Không gian Tên (Namespace)
Một tài liệu XSD hợp lệ luôn bắt đầu bằng phần tử gốc <xsd:schema>. Phần tử này đóng vai trò chứa toàn bộ định nghĩa ràng buộc, khai báo không gian tên XML, và thông tin phiên bản. Mỗi file schema chỉ được phép tồn tại duy nhất một phần tử gốc này.
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/catalog"
elementFormDefault="qualified">
<!-- Định nghĩa phần tử và kiểu dữ liệu ở đây -->
</xsd:schema>
Quản lý Phần tử (Element) và Thuộc tính (Attribute)
Phần tử trong XSD được khai báo bằng thẻ <xsd:element>. Thuộc tính name xác định tên tag, trong khi type quy định kiểu dữ liệu của giá trị (có thể dùng kiểu dựng sẵn hoặc kiểu tùy chỉnh).
<xsd:element name="product" type="xsd:string" />
Các thuộc tính kiểm soát tần suất xuất hiện bao gồm:
| Thuộc tính | Mô tả |
|---|---|
| name | Định danh của phần tử |
| type | Kiểu dữ liệu cơ sở hoặc tùy chỉnh |
| minOccurs | Số lần xuất hiện tối thiểu (mặc định 1, ≥ 0) |
| maxOccurs | Số lần xuất hiện tối đa (mặc định 1, ≥ 0 hoặc "unbounded") |
Tham chiếu & Gán nhóm thay thế:
Để tránh lặp định nghĩa, dùng thuộc tính ref. Để cho phép nhiều tên tag khác nhau trỏ về cùng một kiểu, dùng substitutionGroup.
<xsd:element name="item_id" type="xsd:string" substitutionGroup="ref_code" />
<xsd:sequence>
<xsd:element ref="item_id" />
</xsd:sequence>
Cả hai khai báo XML dưới đây đều hợp lệ khi schema cho phép nhóm thay thế:
<ref_code>SKU-9921</ref_code>
<item_id>SKU-9921</item_id>
Giá trị mặc định & Cố định:
<xsd:element name="warehouse_loc" type="xsd:string" default="HN" />
<xsd:element name="status" type="xsd:string" fixed="active" />
Điều khiển Cấu trúc bằng Model Groups
Các bộ tổ hợp (composers) xác định cách các phần tử con sắp xếp bên trong phần tử cha:
- sequence: Bắt buộc sắp xếp đúng thứ tự khai báo.
- all: Cho phép thứ tự tự do, mỗi phần tử xuất hiện tối đa một lần (trừ khi
minOccurs="0"). - choice: Chỉ chọn duy nhất một trong các phần tử được liệt kê (tính loại trừ lẫn nhau).
<xsd:sequence>
<xsd:element name="sku" type="xsd:string" />
<xsd:element name="price" type="xsd:decimal" />
<xsd:element name="stock" type="xsd:nonNegativeInteger" />
</xsd:sequence>
<xsd:all>
<xsd:element name="sku" type="xsd:string" />
<xsd:element name="price" type="xsd:decimal" />
<xsd:element name="stock" type="xsd:nonNegativeInteger" />
</xsd:all>
<xsd:choice>
<xsd:element name="sku" type="xsd:string" />
<xsd:element name="barcode" type="xsd:string" />
</xsd:choice>
Định nghĩa Thuộc tính Chi tiết
Thuộc tính được khai báo độc lập hoặc lồng trong kiểu phức hợp. Bảng tham chiếu thuộc tính cho <xsd:attribute>:
| Thuộc tính | Chức năng |
|---|---|
| name | Tên thuộc tính |
| type | Kiểu dữ liệu |
| use | optional (mặc định), required, prohibited |
| default / fixed | Giá trị khởi tạo hoặc khóa cứng |
| form | Quy định qualified/unqualified cho attributeFormDefault |
<xsd:element name="order">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="order_id" type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="priority" type="xsd:string" use="optional" />
</xsd:complexType>
</xsd:element>
Đoạn XML hợp lệ tương ứng:
<?xml version="1.0"?>
<order priority="high">
<order_id>ORD-2024-001</order_id>
</order>
Kiểu Dữ liệu và Hệ thống Ràng buộc (Constraints)
XSD cung cấp các kiểu nền tảng như string, boolean, decimal, int, dateTime, short, nonNegativeInteger, v.v. Khi kiểu dựng sẵn chưa đủ chặt chẽ, dùng thẻ <xsd:restriction> kết hợp các facet sau:
| Facet | Ý nghĩa |
|---|---|
| enumeration | Danh sách giá trị được phép |
| length / minLength / maxLength | Giới hạn độ dài chuỗi |
| minInclusive / maxInclusive | Ngưỡng giới hạn dưới/trên (bao gồm điểm mốc) |
| minExclusive / maxExclusive | Ngưỡng giới hạn dưới/trên (không bao gồm điểm mốc) |
| pattern | Biểu thức chính quy (Regex) bắt buộc phải khớp |
| fractionDigit / totalDigits | Số chữ số thập phân và tổng chữ số |
| whiteSpace | preserve, replace, hoặc collapse ký tự trắng |
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="1" />
<xsd:maxInclusive value="500" />
</xsd:restriction>
Các Loại Kiểu Dữ liệu Tùy chỉnh
Simple Type: Mở rộng hoặc hạn chế kiểu dữ liệu cơ bản.
<xsd:simpleType name="validCurrency">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="USD" />
<xsd:enumeration value="EUR" />
<xsd:enumeration value="VND" />
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="payment" type="validCurrency" />
List Type: Tập hợp các giá trị cách nhau bởi khoảng trắng.
<xsd:simpleType name="quantityList">
<xsd:list itemType="xsd:integer" />
</xsd:simpleType>
<xsd:element name="batch_counts" type="quantityList" />
<!-- XML hợp lệ: <batch_counts>10 25 3 100</batch_counts> -->
Union Type: Cho phép giá trị thuộc một trong nhiều kiểu đã định nghĩa.
<xsd:simpleType name="contactRef">
<xsd:union memberTypes="validCurrency quantityList" />
</xsd:simpleType>
<xsd:element name="reference_code" type="contactRef" />
<!-- Hợp lệ: <reference_code>USD</reference_code> hoặc <reference_code>5 10</reference_code> -->
Anonymous Type: Định nghĩa trực tiếp bên trong phần tử khi không cần tái sử dụng kiểu dữ liệu đó.
<xsd:element name="discount_pct">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
Mô hình Nội dung (Content Model) và Mở rộng Linh hoạt
Thẻ <xsd:any> cho phép chèn các phần tử ngoài không gian tên hiện tại vào cấu trúc schema, thường dùng trong các hệ thống plugin hoặc mở rộng module.
<xsd:complexType name="extendedData">
<xsd:sequence>
<xsd:element name="core_id" type="xsd:string" />
<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
Ví dụ Minh họa Tổng hợp
Dưới đây là một schema hoàn chỉnh quản lý cấu hình hệ thống, tích hợp ràng buộc duy nhất (unique), biểu thức chính quy, kiểu phức hợp và thuộc tính bắt buộc.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="system_config">
<xs:complexType>
<xs:sequence>
<xs:element name="component" type="componentType" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:unique name="uniqueComponentName">
<xs:selector xpath="component" />
<xs:field xpath="@id" />
</xs:unique>
</xs:complexType>
</xs:element>
<xs:complexType name="componentType">
<xs:all>
<xs:element name="dependencies" type="depListType" minOccurs="0" maxOccurs="1" />
</xs:all>
<xs:attribute name="id" type="compIdType" use="required" />
<xs:attribute name="deploy_ver" type="verType" use="required" />
</xs:complexType>
<xs:complexType name="depListType">
<xs:sequence maxOccurs="unbounded">
<xs:element name="dep" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="ref_id" type="compIdType" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="compIdType">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z]{2,5}_[a-z0-9]{3,8}" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="verType">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]+\.[0-9]+\.[0-9]+" />
</xs:restriction>
</xs:simpleType>
</xs:schema>