CÔNG NGHỆ THÔNG TIN >> SINH VIÊN BKAP

Validation XML Data với XSD Schema

Đăng lúc: 10:34 AM - 09/01/2024 bởi Charles Chung - 1014

Trong bài này chúng ta sẽ tìm hiểu cách validate dữ liệu XML với XSD Schema

Giới thiệu

Một trong những cách phổ biến nhất để xác thực đầu vào và đầu ra XML là sử dụng XML Schema (XSD), một ngôn ngữ tiêu chuẩn để xác định cấu trúc và các ràng buộc của tài liệu XML. XSD cho phép bạn chỉ định các thành phần, thuộc tính, kiểu dữ liệu và namespace tên được phép hoặc bắt buộc trong tệp XML của bạn. XSD có thể giúp bạn tránh các cuộc tấn công chèn XML và XXE bằng cách từ chối các tài liệu XML không đúng định dạng hoặc độc hại.

Cấu trúc tài liệu XSD

Tài liệu XSD sử dụng cú pháp XML và luôn bắt đầu với phần từ root <xs:schema>....</xs:schema>, các bạn có thể tham khảo cú pháp XSD với phần tử gốc như sau:

  • Không sử dụng namespace

1
2
3
4
5
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
...
</xs:schema>
  • Khai báo đầy đủ namespace
1
2
3
4
5
6
7
8
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://hanam88.com"
xmlns="https://hanam88.com"
elementFormDefault="qualified">
...
...
</xs:schema>

Trong đó:

  • xmlns:xs="http://www.w3.org/2001/XMLSchema" : Chỉ ra rằng các phần tử và kiểu dữ liệu được sử dụng trong lược đồ đến từ namespace "http://www.w3.org/2001/XMLSchema", và trong tài liệu phải sử dụng tiền tố xs: để chỉ định các phần tử và kiểu dữ liệu của namespace đó.
  • targetNamespace="https://hanam88.com" : Chỉ ra rằng các phần tử do người dùng định nghĩa lược đồ này (lưu ý, đến, từ, tiêu đề, nội dung.) đến từ namespace "https://www.w3schools.com".
  • xmlns="https://hanam88.com" : chỉ ra namespace mặc định của tài liệu này.
  • elementFormDefault="qualified" : chỉ ra rằng mọi phần tử được sử dụng bởi tài liệu XML Instance đã được khai báo trong lược đồ này phải đủ tiêu chuẩn về namespace.

Liên kết tài liệu XSD với XML

  • Không sử dụng namespace

1
2
3
4
5
6
7
<?xml version="1.0"?>
<note xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="note.xsd">
    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
</note>
  • Có sử dụng namespace
1
2
3
4
5
6
7
8
9
<?xml version="1.0"?>
<note xmlns="https://hanam88.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://hanam88.com note.xsd">
    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
</note>

Trong đó

  • xmlns="https://hanam88.com" :chỉ định khai báo namespace mặc định. Tuyên bố này cho trình xác thực lược đồ biết rằng tất cả các thành phần được sử dụng trong tài liệu XML này đều được khai báo trong namespace "https://hanam88.com".
  • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance": chỉ ra đây là thể hiện của namespace  "http://www.w3.org/2001/XMLSchema"
  • xsi:schemaLocation="https://hanam88.com note.xsd" : chỉ là namespace và đường dẫn tệp tin XSD sử dụng namespace đó, chúng cách nhau 1 khoảng trắng.

Phần tử XSD đơn giản (XSD Simple Element)

XML XSD xác định các thành phần của tệp XML của bạn. XSD Simple Element là phần tử XML chỉ chứa văn bản. Nó không thể chứa bất kỳ phần tử con hoặc thuộc tính nào khác.

Cú pháp định nghĩa một phần tử đơn giản

1
<xs:element name="xxx" type="yyy"/>

Trong đó

  • xxx là tên của phần tử và yyy là kiểu dữ liệu của phần tử.
  • Lược đồ XML có rất nhiều kiểu dữ liệu tích hợp sẵn. Các loại phổ biến nhất là:
    • xs: string
    • xs: decimal
    • xs: integer
    • xs:boolean
    • xs: date
    • xs: time

Ví dụ

Đây là một vài phần tử XML

1
2
3
<lastname>Refsnes</lastname>
<age>36</age>
<dateborn>1970-03-27</dateborn>

Đây là XSD simple element định nghĩa phần tử XML trên

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

Định nghĩa giá trị cố định và mặc định cho phần tử (fixed and default value)

Các phần tử đơn giản có thể có giá trị mặc định HOẶC giá trị cố định được chỉ định. Giá trị mặc định được tự động gán cho phần tử khi không có giá trị nào khác được chỉ định. Trong ví dụ sau, giá trị mặc định là "red":

1
<xs:element name="color" type="xs:string" default="red"/>

Một giá trị cố định cũng được tự động gán cho phần tử và bạn không thể chỉ định giá trị khác. Trong ví dụ sau, giá trị mặc định là "red":

1
<xs:element name="color" type="xs:string" fixed="red"/>

Thuộc tính XSD (XSD Attribute)

Tất cả các thuộc tính được khai báo là kiểu đơn giản. Các phần tử đơn giản không thể có thuộc tính. Nếu một phần tử có các thuộc tính thì nó được coi là thuộc loại phức tạp. Nhưng bản thân thuộc tính đó luôn được khai báo là một kiểu đơn giản. Sau đây là cú pháp định nghĩa một thuộc tínn

1
<xs:attribute name="xxx" type="yyy"/>

Trong đó

  • xxx là tên của phần tử và yyy là kiểu dữ liệu của phần tử.
  • Lược đồ XML có rất nhiều kiểu dữ liệu tích hợp sẵn. Các loại phổ biến nhất là:
    • xs: string
    • xs: decimal
    • xs: integer
    • xs:boolean
    • xs: date
    • xs: time

Ví dụ

Đây là một phần tử với thuộc tính "lang"

1
<lastname lang="EN">Chung</lastname>

và đây là phần định nghĩa khớp với thuộc tính trên

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

Phần tử hoặc thuộc tính với kiểu Id

1
<xs:attribute name="Id" type="xs:ID"/>

Phần tử hoặc thuộc tính kiểu unique

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<xs:element name="persons">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="person" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="firstname" type="xs:string"/>
                        <xs:element name="lastname" type="xs:string"/>
                        <xs:element name="email" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
    <xs:unique name="emailUnique">
        <xs:selector xpath="person"/>
        <xs:field xpath="email"/>
   </xs:unique>
</xs:element>

Định nghĩa giá trị cố định và mặc định cho thuộc tính (fixed and default value)-Tương tự định nghĩa trong phần tử

Thuộc tính tủy chọn và bắt buộc

Các thuộc tính là tùy chọn theo mặc định. Để chỉ định rằng thuộc tính này là bắt buộc, hãy sử dụng thuộc tính "use":

1
<xs:attribute name="lang" type="xs:string" use="required"/>

Phần tử XSD phức tạp (XSD Complex Element)

Phần tử phức hợp là phần tử XML chứa các phần tử và/hoặc thuộc tính khác. Có bốn loại phần tử phức tạp:

  • phần tử trống
1
<product pid="1345"/>
  • phần tử chỉ chứa các phần tử khác
1
2
3
4
<employee>
  <firstname>Charles</firstname>
  <lastname>Chung</lastname>
</employee>
  • các phần tử chỉ chứa văn bản
1
<food type="dessert">Ice cream</food>
  • các phần tử chứa cả phần tử khác và văn bản
1
2
3
<description>
It happened on <date lang="norwegian">03.03.99</date> ....
</description>

Định nghĩa phần tử phức tạp

Sau đây là code định nghĩa phần tử employee 

1
2
3
4
5
6
7
8
<xs:element name="employee">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="firstname" type="xs:string"/>
      <xs:element name="lastname" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

Phần tử phức tạp với 1 tên và sử dụng lại nhiều lần, hãy xem ví dụ sau

1
2
3
4
5
6
7
8
9
<xs:element name="employee" type="personinfo"/>
<xs:element name="student" type="personinfo"/>
<xs:element name="member" type="personinfo"/>
<xs:complexType name="personinfo">
  <xs:sequence>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

Phần tử phức tạp mở rộng từ kiểu phức tạp đã có sẵn, hãy xem ví dụ sau

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<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>

Phần tử phức tạp với phần tử và huộc tính (element and attribute)

1
2
3
4
5
6
7
8
9
<xs:element name="employee">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="firstname" type="xs:string"/>
            <xs:element name="lastname" type="xs:string"/>
          </xs:sequence>
          <xs:attribute name="active" type="xs:boolean"/>
    </xs:complexType>
</xs:element>

Phần tử phức tạp với chỉ thuộc tính (only attribute)

1
2
3
4
5
<xs:element name="product">
  <xs:complexType>
    <xs:attribute name="img" type="xs:string"/>
  </xs:complexType>
</xs:element>

Phần tử phức tạp với thuộc tính và text (attribute and text)

1
2
3
4
5
6
7
8
9
<xs:element name="shoesize">
  <xs:complexType>
    <xs:simpleContent>
      <xs:extension base="xs:integer">
        <xs:attribute name="country" type="xs:string" />
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
</xs:element>

Phần tử phức tạp lẫn giữa phần tử và văn bản (mixed)

1
2
3
4
5
6
7
8
9
<xs:element name="letter">
  <xs:complexType mixed="true">
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="orderid" type="xs:positiveInteger"/>
      <xs:element name="shipdate" type="xs:date"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

Phần tử với số lần xuất hiện, sử dụng thuộc tính minOccurs="số>=0" và maxOccurs="số>=0 hoặc unbounded"

1
2
3
4
5
6
7
8
<xs:element name="Employee"  minOccurs="0" maxOccurs="unbounded">
     <xs:complexType>
          <xs:sequence>
                <xs:element name="firstname" type="xs:string"/>
                <xs:element name="lastname" type="xs:string"/>
          </xs:sequence>
     </xs:complexType>
</xs:element>

Phần tử với <xs:any> (cho phép mở rộng thêm phần tử mà không cần chỉ ra lược đồ), hãy xem ví dụ sau, sau <lastname> bạn có thể thêm bất cứ phần tử gì

1
2
3
4
5
6
7
8
9
<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:sequence>
  </xs:complexType>
</xs:element>

Phần tử với <xs:anyAttribute> (cho phép mở rộng thêm bất kỳ thuộc tính gì bên trong phần tử), hãy xem ví dụ sau

1
2
3
4
5
6
7
8
9
<xs:element name="person">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="firstname" type="xs:string"/>
      <xs:element name="lastname" type="xs:string"/>
    </xs:sequence>
    <xs:anyAttribute/>
  </xs:complexType>
</xs:element>

Phần tử tham chiếu

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="person">
   <xs:complexType>
    <xs:sequence>
        <xs:element ref="firstname"/>
        <xs:element ref="lastname"/>
    </xs:sequence>
   </xs:complexType>
</xs:element>

Các Indicator

<xs:all> : các phần tử bên trong xuất hiện không theo thứ tự

<xs:sequence> : các phần tử bên trong xuất hiện theo đúng thứ tự

<xs:choice> : các phần tử bên trong có thể xuất hiện 1 trong số đó

Hạn chế giá trị của phần tử, thuộc tính (Restriction value)

Các hạn chế được sử dụng để xác định các giá trị được chấp nhận cho các phần tử hoặc thuộc tính XML. Các hạn chế đối với các phần tử XML được gọi là các khía cạnh. Hãy xem một số ví dụ sau

Hạn chế giá trị số, ví dụ phần tử age từ 0-120

1
2
3
4
5
6
7
8
<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>

Hạn chế tập giá trị, ví dụ phần tử car chỉ được nhận một trong các giá trị

1
2
3
4
5
6
7
8
9
<xs:element name="car">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:enumeration value="Audi"/>
      <xs:enumeration value="Golf"/>
      <xs:enumeration value="BMW"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

Hạn chế giá trị phải thỏa mãn một pattern (sử dụng regular expression)

1
2
3
4
5
6
7
<xs:element name="letter">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:pattern value="[a-z]"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

Hạn chế độ dài tối thiểu, tối đa

1
2
3
4
5
6
7
8
<xs:element name="password">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:minLength value="5"/>
      <xs:maxLength value="8"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

Download một số ví dụ về XSD 

thay lời cảm ơn!

QUẢNG CÁO - TIẾP THỊ