Chương 1 CƠ SỞ LÝ THUYẾT
1.4. Công cụ hỗ trợ trích rút thông tin
1.4.2. Cú pháp và ngữ nghĩa
Một biểu thức XPath có thể là một đường dẫn vị trí (location path), đây là loại biểu thức quan trọng nhất trong XPath. Một location path bao gồm một hoặc nhiều bước (location step). Mỗi bước gồm có 3 thành phần sau:
Một axis specifier (chỉ định hướng).
Một node test.
Một hoặc nhiều predicate.
Biểu thức XPath luôn được đánh giá một cách tương đối với một node ngữ cảnh. Một chỉ định hướng (axis specifier) “child” sẽ cho biết hướng di chuyển (để tìm kiếm) sẽ là hướng đến các node con của node ngữ cảnh. Node test và predicate sẽ dùng để lọc các node thu được một cách chi tiết hơn. Ví dụ node test “A” đòi hỏi tất cả các node nhận được phải có tên là “A”. Một predicate dùng để chỉ ra các node này phải có một số đặc điểm nào đó nữa. Cú pháp của biểu thức XPath cũng có thể ở hai dạng: rút gọn và đầy đủ.
1.4.2.1. Cú pháp rút gọn
Ví dụ một tài liệu XML như sau:
<?xml version=”1.0” encoding=”UTF-8”?>
<A>
<B>
<C/>
</B>
</A>
Một biểu thức XPath đơn giản:
/A/B/C
Biểu thức XPath này sử dụng giá trị mặc định của các axis specifier đó là giá trị con và các bước của biểu thức đều không sử dụng predicate. Biểu thức này chọn ra các phần tử C nào mà là con của các phần tử B và các phần tử B này cũng phải là con của các phần tử A. Cú pháp này của XPath có nét tương đồng
với cú pháp của URI (Uniform Resource Identifier) cũng như cú pháp đường dẫn tệp của các hệ điều hành Unix.
Một biểu thức phức tạp hơn:
A//B/*[1]
Biểu thức này chọn ra phần tử có tên tùy ý và phải là phần tử đầu tiên (“[1]”) trong các phần tử con của phần tử B, phần tử B này phải là con hoặc cháu chắt (“//”) của một phần tử A nào đó, phần tử A này lại là con của node ngữ cảnh (do biểu thức không bắt đầu bởi “/”). Nếu phần tử A có nhiều node con cháu cùng tên B thì biểu thức này sẽ trả về một tập các node con đầu tiên của các phần tử B này.
1.4.2.2. Cú pháp đầy đủ
Hai biểu thức XPath ở trên khi được viết lại ở dạng đầy đủ thì chúng sẽ như sau:
/child::A/child::B/child::C
child::A/descendant-or-self::node()/child::B/child::*[position()=1]
Có thể thấy ở dạng đầy đủ, axis specifier được viết tường minh trong mỗi bước của biểu thức, nối tiếp bởi hai dấu hai chấm ::, rồi đến node test như A, B hoặc node() trong ví dụ trên.
Để truy vấn với đường dẫn tuyệt đối nghĩa là đi từ root của tài liệu XML đến các thành phần cần truy cập, XPath quy định với cú pháp bắt đầu bằng dấu /.
Để truy vấn với đường dẫn tương đối để có thể truy cập đến thành phần bất kỳ thỏa điều kiện, XPath quy định cú pháp sử dụng với dấu //.
Để truy vấn đến một thành phần bất kỳ mà không cần biết tên của nó là gì, XPath qui định ký tự sử dụng là *.
Để truy cập thuộc tính của một node, XPath qui định thuộc tính truy vấn phải có cú pháp bắt đầu là @. Ví dụ @tênThuộcTính.
Để truy cập đến giá trị của một biến được định nghĩa, XPath qui định biến truy vấn phải có cú pháp bắt đầu là $. Ví dụ $tênBiến.
Điều kiện khi truy vấn được đặt trong dấu [].
Truy vấn lựa chọn nodes:
Biểu thức Định nghĩa
tênNode Chọn tất cả các node con của tênNode / Chọn tất cả các node tính từ root
// Chọn tất cả node tính từ node hiện hành
. Chọn node hiện hành
.. Chọn node cha của node hiện hành
Axis Specifier:
Bảng 1.1. Một số cú pháp của XPath
Axis Định nghĩa Cú pháp
rút gọn Ví dụ ancestor Chọn tất cả các node trên
của node hiện hành ancestor-
or-self
Chọn tất cả các node trên của node hiện hành và chính nó
attribute Chọn tất cả các thuộc tính
của node hiện hành @ @abc là viết tắt của attribute::abc child Chọn node con của node
hiện hành
xyz là viết tắt của child::xyz
descendant Chọn tất cả các node dưới của node hiện hành
descendant- or-self
Chọn tất cả các node dưới của node hiện hành và chính nó
//
//B là viết tắt của descendant-or- self::node()/child::
B
Axis Định nghĩa Cú pháp
rút gọn Ví dụ following Chọn tất cả các node sau khi
tag đóng của node hiện hành following-
sibling
Chọn tất cả các node ngang cấp sau khi tag đóng của node hiện hành
namespace Chọn tất cả namespace của node hiện hành
parent Chọn tất cả node cha của
node hiện hành ..
A/../B là viết tắt của
A/parent::node()/c hild::B
preceding
Chọn tất cả các thành phần trước khi bắt đầu tag mở của node hiện hành
preceding- sibling
Chọn tất cả các node ngang hàng trước khi bắt đầu tag mở của node hiện hành
self Chọn node hiện hành . . là viết tắt của self::node()
Một số node test:
comment(): tìm một node chú thích, ví dụ <!-- comment -->.
text(): tìm một node có kiểu là text, ví dụ hello trong <a>hello<b>
world</b></a>.
processing-instruction(): tìm các chỉ dẫn xử lý của XML, ví dụ processing-instruction(‘php’) sẽ trả về node <?php echo $a; ?>.
node(): tìm bất kỳ node nào.
Predicate:
Một bước của biểu thức XPath có thể có nhiều predicate. Mỗi predicate cũng được viết dưới dạng biểu thức và nằm trong cặp ngoặc vuông [ ], các node nhận được của biểu thức sẽ phải thỏa điều kiện của các predicate. Ví dụ a[@href=’help.php’] sẽ chỉ trả về các phần tử có tên là a (trong các node con của node ngữ cảnh) và có một thuộc tính href với giá trị help.php. Các predicate có thể trả về giá trị boolean, số nguyên, hoặc một tập các node. Nếu giá trị trả về của predicate là số nguyên thì giá trị này được hiểu là vị trí của node cần tìm, ví dụ p[1] trả về phần tử p đầu tiên, p[last()] trả về phần tử p cuối cùng. Trong trường hợp trả về một tập node thì khi tập node khác rỗng giá trị sẽ được hiểu là true, ví dụ p[@id] trả về các node p có thuộc tính id.
1.4.2.3. Các hàm và toán tử
XPath 1.0 định nghĩa 4 kiểu dữ liệu: kiểu tập node (node-set), kiểu chuỗi ký tự (string), kiểu số (number) và kiểu logic (boolean).
Các toán tử phổ biến được dùng trong XPath:
Toán tử hội “|“ để tìm hội của hai tập node.
Toán tử logic “and” và “or” (và một hàm not(boolean) để phủ định một biểu thức boolean).
Các toán tử cộng trừ nhân chia “+”, “-“, “*”, “div” và “mod”.
Các toán tử so sánh “=”, “!=”, “<”, “>”, “<=”, “>=”.
Các hàm phổ biến trong thư viện hàm của XPath 1.0:
position(): trả về giá trị kiểu số thể hiện vị trí của node trong một chuỗi các node.
count(node-set): trả về số node có trong node-set.
string(object?): chuyển bất kỳ kiểu dữ liệu nào thành kiểu chuỗi. Nếu tham số là kiểu node-set thì hàm này trả về giá trị chuỗi của node đầu tiên trong node-set (theo thứ tự xuất hiện trong tài liệu).
contains(s1, s2): trả về true nếu s1 chứa s2.
true(), false(): trả về các giá trị true, false tương ứng.
position(): trả về vị trí của node.
Một số ví dụ:
//item[@price > 2*@discount]
Trả về các node item có thuộc tính price lớn hơn hai lần giá trị thuộc tính discount của nó;
//product[contains(comment, ‘bad’)]
Trả về các node product có node con comment chứa từ ‘bad’.