Nối tiếp về tìm hiểu XML thì hôm nay mình sẽ viết tiếp về phần XML DOM – Cấu trúc thư mục của XML. Cùng tìm hiểu nào!
1. DOM là gì?
DOM là viết tắt của từ Document Object Model, định nghĩa chuẩn của truy cập tài liệu.
Nó định nghĩa các đối tượng và thuộc tính của tất cả các phần tử tài liệu, và các phương thức truy cập vào chúng.
DOM gồm có 3 phần:
- Core DOM: mô hình chuẩn cho các tài liệu có cấu trúc.
- XML DOM: mô hình chuẩn cho các tài liệu XML
- HTML DOM: mô hình chuẩn cho các tài liệu HTML
XML DOM
- Là một chuẩn W3C.
- Là mô hình đối tượng chuẩn cho XML.
- Nó định nghĩa một chuẩn cho truy cập và thao tác với tài liệu XML
- Là một giao diện lập trình chuẩn cho XML
2. Các nút DOM
Mọi thứ trong một tài liệu XML đều là nút.
- Document node: Toàn bộ tài liệu là nút tài liệu.
- Element node: Mỗi phần tử XML là nút phần tử.
- Text node: Văn bản trong các phần tử XML là nút văn bản.
- Attribute node: Mỗi thuộc tính là nút thuộc tính.
- Comment node: Chú thích là nút chú thích.
3. Cây nút XML DOM
- XML DOM coi một tài liệu XML là một cấu trúc cây, gọi là cây nút.
- Ta có thể truy cập tới tất cả các nút của cây và có thể thêm mới, sửa, xóa các phần tử.
Mình sẽ lấy ví dụ để phân tích dễ hơn và mình sẽ dùng ví dụ này xuyên suốt cả bài luôn nhé! (books.html)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <span class="token php language-php"><span class="token delimiter important"><?</span>xml version<span class="token operator">=</span><span class="token double-quoted-string string">"1.0"</span> encoding<span class="token operator">=</span><span class="token double-quoted-string string">"ISO-8859-1"</span><span class="token delimiter important">?></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>bookstore</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>book</span> <span class="token attr-name">category</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>cooking<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>title</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Everyday Italian<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>author</span><span class="token punctuation">></span></span>Giada De Laurentiis<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>author</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>year</span><span class="token punctuation">></span></span>2005<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>year</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>price</span><span class="token punctuation">></span></span>30.00<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>price</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>book</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>book</span> <span class="token attr-name">category</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>children<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>title</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Harry Potter<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>author</span><span class="token punctuation">></span></span>J K. Rowling<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>author</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>year</span><span class="token punctuation">></span></span>2005<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>year</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>price</span><span class="token punctuation">></span></span>29.99<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>price</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>book</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>book</span> <span class="token attr-name">category</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>web<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>title</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>XQuery Kick Start<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>author</span><span class="token punctuation">></span></span>James McGovern<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>author</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>author</span><span class="token punctuation">></span></span>Per Bothner<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>author</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>author</span><span class="token punctuation">></span></span>Kurt Cagle<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>author</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>author</span><span class="token punctuation">></span></span>James Linn<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>author</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>author</span><span class="token punctuation">></span></span>Vaidyanathan Nagarajan<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>author</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>year</span><span class="token punctuation">></span></span>2003<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>year</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>price</span><span class="token punctuation">></span></span>49.99<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>price</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>book</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>book</span> <span class="token attr-name">category</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>web<span class="token punctuation">"</span></span> <span class="token attr-name">cover</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>paperback<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>title</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Learning XML<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>author</span><span class="token punctuation">></span></span>Erik T. Ray<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>author</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>year</span><span class="token punctuation">></span></span>2003<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>year</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>price</span><span class="token punctuation">></span></span>39.95<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>price</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>book</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>bookstore</span><span class="token punctuation">></span></span> |
Từ ví dụ trên ta sẽ có được 1 cây thư mục như sau:
Nhìn vào hình có lẽ mọi người cũng đã hình dung được cấu trúc cây rồi đúng không ạ.
Nút gốc là
<bookstore>
.Các nút khác trong tài liệu phải nằm trong nút gốc này.
Dưới nút gốc có 4 nút
<book>
. Trong mỗi nút<book>
là các nút con. Với nút đầu tiên thì nút con là<title>, <author>, <year>, <price>
.Mỗi nút con này chứa các nút text:
"Everyday Italian", "Giada De Laurentiis", "2005", "30.00"
Note: text của nút phần tử được chứa trong nút text.
- Ví dụ:
<year>2005</year>,
nút phần tử <year> có một nút text có giá trị “2005” và “2005” không phải giá trị của nút phần tử year.
- Ví dụ:
Như vậy qua ví dụ trên ta thấy các nút trong cây có mối quan hệ phân cấp với các nút khác.
- Nút đỉnh sẽ là nút gốc của cây.
- Mỗi nút (trừ nút gốc) đều có 1 nút cha.
- Một nút có thể có không/một/nhiều nút con
- Nút lá là nút không có nút con.
- Các nút anh em là các nút có cùng nút cha.
4. Các thuộc tính của XML DOM
Một số thuộc tính đặc trưng của XML DOM là:
- x.nodeName: tên của x
- x.nodeValue: giá trị của x
- x.parentNode: nút cha của x
- x.childNodes: các nút con của x
- x.attributes: các nút thuộc tính của x
Phương thức XML DOM
Phương thức | ĐỊnh nghĩa | Ví dụ |
---|---|---|
x.getElementsByTagName(name) | lấy về tất cả các phần tử mà tag có tên là name | x = xmlDoc.getElementsByTagName(“title”)[0].childNodes[0].nodeValue |
x.appendChild(node) | thêm một nút con vào nút x | x = xmlDoc.getElementsByTagName(“book”)[0]; x.appendChild(newElement) |
x.removeChild(node) | loại một nút con ra khỏi nút x | y = xmlDoc.getElementsByTagName(“book”)[0]; xmlDoc.documentElement.removeChild(y); |
Để tính chiều dài danh sách nút DOM, ta có thể:
- Sử dụng thuộc tính length của danh sách nút
- Hoặc sử dụng vòng lặp để duyệt
- Ví dụ
1 2 3 4 5 6 7 | xmlDoc<span class="token operator">=</span><span class="token function">loadXMLDoc</span><span class="token punctuation">(</span><span class="token double-quoted-string string">"books.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> x<span class="token operator">=</span>xmlDoc<span class="token punctuation">.</span><span class="token function">getElementsByTagName</span><span class="token punctuation">(</span><span class="token double-quoted-string string">"title"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>i<span class="token operator"><</span>x<span class="token punctuation">.</span>length<span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> document<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>x<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">.</span>childNodes<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>nodeValue<span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token double-quoted-string string">" <br /> "</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
5. Thông tin nút XML DOM
- Mỗi nút là một đối tượng và chúng đều có phương thức và thuộc tính.
- Có ba thuộc tính quan trọng của một nút:
nodeName, nodeValue, nodeType
Thuộc tính nodeName
- Cho biết tên của 1 nút
- Read-only
- nodeName của một nút phần tử chính là tên thẻ
- nodeName của một nút thuộc tính chính là tên thuộc tính
- nodeName của một nút text là #text
- nodeName của một nút tài liệu là #document
- VÍ dụ
1 2 3 4 5 | <span class="token operator"><</span>script<span class="token operator">></span> xmlDoc<span class="token operator">=</span><span class="token function">loadXMLDoc</span><span class="token punctuation">(</span><span class="token double-quoted-string string">"books.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>xmlDoc<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>nodeName<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span> |
Thuộc tính nodeValue
- Cho biết giá trị của nút
- nodeValue của các nút phần tử là không xác định
- nodeValue của nút text chính là text
- nodeValue của nút thuộc tính là giá trị thuộc tính
- Nó lấy về giá trị của một phần tử
- Ví dụ:
1 2 3 4 5 6 7 8 | <span class="token operator"><</span>script<span class="token operator">></span> xmlDoc<span class="token operator">=</span><span class="token function">loadXMLDoc</span><span class="token punctuation">(</span><span class="token double-quoted-string string">"books.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> x<span class="token operator">=</span>xmlDoc<span class="token punctuation">.</span><span class="token function">getElementsByTagName</span><span class="token punctuation">(</span><span class="token double-quoted-string string">"title"</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>childNodes<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// Lấy giá trị nút text của phần tử <title> đầu tiên</span> txt<span class="token operator">=</span>x<span class="token punctuation">.</span>nodeValue<span class="token punctuation">;</span> document<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>txt<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span> |
Thuộc tính nodeType
- Cho biết kiểu của nút
- Read-only
- Một số kiểu quan trọng:
Node type | NodeType |
---|---|
Element | 1 |
Attribute | 2 |
Text | 3 |
Comment | 8 |
Document | 9 |
- Ví dụ
1 2 3 4 5 6 7 | <span class="token operator"><</span>script<span class="token operator">></span> xmlDoc<span class="token operator">=</span><span class="token function">loadXMLDoc</span><span class="token punctuation">(</span><span class="token double-quoted-string string">"books.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>xmlDoc<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>nodeName<span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token double-quoted-string string">"<br>"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> document<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>xmlDoc<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>nodeType<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span> |
6. Định hướng trong cây
- Là việc truy cập vào các nút thông qua mối quan hệ giữa các nút.
- Các thuộc tính của nút
Thuộc tính | Định nghĩa |
---|---|
parentNode | Tất cả các nút (trừ gốc) đều có duy nhất một nút cha. |
childNodes | Tham chiếu đến các nút con trực tiếp của nút hiện tại. Kết quả là 1 mảng các đối tượng |
firstChild | Trả về nút con đầu tiên của nút hiện tại (tương đương với Node.childNodes[0]). |
lastChild | Trả về nút con cuối cùng của nút hiện tại (tương đương với Node.childNodes[Element.childNodes.length-1]). |
nextSibling | Gọi đến nút anh em nằm liền kề sau với nút hiện tại. |
previousSibling | Gọi đến nút anh em nằm liền kề trước với nút hiện tại. |
Note: Một số trình duyệt (như FireFox) coi kí tự trắng và xuống dòng là nút text (và đây là nút text rỗng). Để tránh truy cập vào phần tử text rỗng này ta sử dụng hàm kiểm tra kiểu nút
1 2 3 4 5 6 7 8 | <span class="token keyword">function</span> <span class="token function">get_nextSibling</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">{</span> y<span class="token operator">=</span>n<span class="token punctuation">.</span>nextSibling<span class="token punctuation">;</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>y<span class="token punctuation">.</span>nodeType<span class="token operator">!=</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">{</span> y<span class="token operator">=</span>y<span class="token punctuation">.</span>nextSibling<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> y<span class="token punctuation">;</span> <span class="token punctuation">}</span> |
7. Thao tác với các nút
Phương thức | Định nghĩa | Ví dụ |
---|---|---|
getAttribute() | Lấy giá trị text của thuộc tính | xmlDoc.getElementsByTagName(“title”)[0].getAttribute(“lang”); |
getAttributeNode() | Trả về một nút thuộc tính. | x=xmlDoc.getElementsByTagName(“title”)[0].getAttributeNode(“lang”); txt=x.nodeValue; |
setAttribute() | Tạo mới nếu chưa có thuộc tính, ghi đè nếu đã có thuộc tính | x=xmlDoc.getElementsByTagName(‘book’); x[0].setAttribute(“category”,”food”); |
removeChild() | Xóa một nút | y=xmlDoc.getElementsByTagName(“book”)[0]; xmlDoc.documentElement.removeChild(y); |
removeAttribute() | Xóa một thuộc tính | x=xmlDoc.getElementsByTagName(“book”); x[0].removeAttribute(“category”); |
replaceChild() | Thay thế một nút phần tử | y=xmlDoc.getElementsByTagName(“book”)[0]; xmlDoc.documentElement;.replaceChild(newNode,y); // newNode là 1 node mới dùng để thay thế |
replaceData() | Thay thế dữ liệu trong một nút text với 3 tham số truyền vào: offset: vị trí kí tự đầu tiên sẽ thay thế, bắt đầu từ 0. length: số kí tự cần thay thế. string: chuỗi mới cần chèn vào | x=xmlDoc.getElementsByTagName(“title”)[0].childNodes[0]; x.replaceData(0,8,”Easy”); |
createAttribute() | Tạo một nút thuộc tính mới | xmlDoc.createAttribute(“edition”); |
setAttribute() | Tạo nút thuộc tính mới nếu nó chưa tồn tại. | x=xmlDoc.getElementsByTagName(‘book’); x[0].setAttribute(“edition”,”first”); |
createTextNode() | Tạo một nút text | xmlDoc.createElement(“edition”).createTextNode(“first”); |
createComment() | Tạo nút comment | xmlDoc.createComment(“Revised March 2008”); |
appendChild() | Thêm một nút con vào nút hiện tại. | newel=xmlDoc.createElement(“edition”); x=xmlDoc.getElementsByTagName(“book”)[0]; x.appendChild(newel); |
insertBefore() | Chèn một nút trước một nút con xác định. | newNode=xmlDoc.createElement(“book”); x=xmlDoc.documentElement; y=xmlDoc.getElementsByTagName(“book”)[3]; x.insertBefore(newNode,y); |
insertData() | Thêm dữ liệu vào nút text đang có với 2 tham số: offset: chỉ số bắt đầu chèn kí tự (tính từ 0), string: chuỗi cần chèn | x=xmlDoc.getElementsByTagName(“title”)[0].childNodes[0]; x.insertData(0,”Easy “); |
cloneNode() | Tạo ra một bản sao của một nút xác định. Có 1 tham số nhận giá trị true/false, cho biết nút sao có bao gồm các thuộc tính và các nút con của nút ban ñầu hay không. | oldNode=xmlDoc.getElementsByTagName(‘book’)[0]; newNode=oldNode.cloneNode(true); |
Trên đây là những kiến thức cơ bản về phần XML DOM mà mình tìm hiểu. Để có thể chạy được các ví dụ trên, mọi người lên W3Shool để thực hành nhé!
Tài liệu tham khảo:
- https://www.w3schools.com/xml/dom_intro.asp
- Bài giảng Tích hợp dữ liệu & XML – DHBKHN