Duyệt cây nút XML DOM

Duyệt (Traverse) có nghĩa là duyệt cây nút.

Duyệt cây nút

Bạn thường xuyên cần lặp qua tài liệu XML, chẳng hạn như: khi bạn muốn lấy giá trị của mỗi phần tử.

Quá trình này được gọi là “duyệt cây nút”

Dưới đây là ví dụ lặp qua tất cả các nút con của <book> và hiển thị tên và giá trị của chúng:

Mô hình

<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var x, i ,xmlDoc;
var txt = "";
var text = "<book>" +
"<title>雅舍谈吃</title>" +
"<author>梁实秋</author>" +
"<year>2013</year>" +
"</book>";
parser = new DOMParser();
xmlDoc = parser.parseFromString(text,"text/xml");
// documentElement luôn đại diện cho phần tử gốc
x = xmlDoc.documentElement.childNodes;
for (i = 0; i < x.length ;i++) {
    txt += x[i].nodeName + ": " + x[i].childNodes[0].nodeValue + "<br>";
}
document.getElementById("demo").innerHTML = txt;
</script>
</body>
</html>

Thử trực tiếp

Giải thích ví dụ:

  1. Chuyển tải chuỗi XML vào xmlDoc Trong
  2. Lấy phần tử con của phần tử gốc
  3. Xuất ra tên của mỗi phần tử con và giá trị của phần tử văn bản của nó

Các khác biệt trong việc phân tích DOM của các trình duyệt

Tất cả các trình duyệt hiện đại đều hỗ trợ quy định W3C DOM.

Nhưng, giữa các trình duyệt có một số khác biệt.

Cách xử lý khoảng trống và dòng mới của chúng

DOM - Khoảng trống và dòng mới

XML thường chứa ký tự xuống dòng hoặc khoảng trống giữa các phần tử. Khi chỉnh sửa tài liệu bằng các trình chỉnh sửa đơn giản như Notepad, thường xảy ra tình trạng này.

Ví dụ dưới đây (được chỉnh sửa bằng Notepad) chứa CR/LF (ký tự换 dòng) giữa mỗi dòng và hai khoảng trống trước mỗi phần tử con:

<book>
  <title>雅舍谈吃</title>
  <author>梁实秋</author>
  <press>江苏文艺出版社</press>
  <year>2013</year>
  <price>35</price>
  <ISBN>9787539962771</ISBN>
</book>

Internet Explorer 9 và các phiên bản trước đó sẽ không coi khoảng trống hoặc dòng mới là phần tử văn bản, trong khi các trình duyệt khác sẽ làm như vậy.

Dưới đây là ví dụ sẽ hiển thị số lượng phần tử con của phần tử gốc (books.xml). Phiên bản IE9 và trước đó sẽ hiển thị 6 phần tử con, trong khi IE10 và các phiên bản sau này cũng như các trình duyệt khác sẽ hiển thị 9 phần tử con:

Mô hình

function myFunction(xml) {
var xmlDoc = xml.responseXML;
    x = xmlDoc.documentElement.childNodes;
    document.getElementById("demo").innerHTML =
    "Số lượng nút con: " + x.length;
}

Thử trực tiếp

PCDATA - Dữ liệu ký tự được phân tích (Parsed Character Data)

Bộ phân tích XML thường sẽ phân tích tất cả văn bản trong tài liệu XML.

Khi phân tích phần tử XML, bộ phân tích cũng sẽ phân tích văn bản giữa các dấu hiệu XML:

<message>Text này cũng sẽ được phân tích</message>

Bộ phân tích thực hiện thao tác này vì phần tử XML có thể chứa các phần tử khác, như ví dụ này, trong đó phần tử <name> chứa hai phần tử khác (first và last):

<name><first>Bill</first><last>Gates</last></name>

Bộ phân tích sẽ phân tích nó thành các phần tử con sau:

<name>
  <first>Bill</first>
  <last>Gates</last>
</name>

“Phân tích dữ liệu ký tự” (PCDATA) là thuật ngữ được sử dụng để mô tả văn bản dữ liệu sẽ được bộ phân tích XML phân tích.

CDATA - Dữ liệu ký tự không được phân tích (Unparsed Character Data)

Termin CDATA được sử dụng để mô tả văn bản dữ liệu không nên được bộ phân tích XML phân tích.

"<" và "&" và các ký tự khác như "

"<" sẽ tạo ra lỗi, vì bộ phân tích sẽ giải thích nó là đầu của phần tử mới.

"&" sẽ tạo ra lỗi, vì bộ phân tích sẽ giải thích nó là đầu của ký tự thực thể.

Một số văn bản (ví dụ: mã vạch JavaScript) chứa nhiều "<" hoặc "&" ký tự. Để tránh lỗi, có thể định nghĩa mã vạch script là CDATA.

CDATA phần trong đó tất cả nội dung sẽ bị bộ phân tích bỏ qua.

CDATA phần được "<![CDATA[" Bắt đầu, bằng "]]>" Kết thúc:

<script>
<![CDATA[
function matchwo(a,b) {
    if (a < b && a < 0) {
        return 1;
    else {
        return 0;
    }
}
]]>
</script>

Trong ví dụ trên, bộ giải thích sẽ bỏ qua tất cả nội dung trong phần CDATA.

Lưu ý về phần CDATA:

Phần CDATA không thể chứa chuỗi "]]>". Không được phép đệm phần CDATA.

Ký tự " đánh dấu kết thúc phần CDATA]]>" Không thể chứa khoảng trống hoặc ký tự xuống dòng.