Обход означает перебор или перемещение в цикле по дереву узлов.
Обход дерева узлов
Часто возникает необходимость пройтись в цикле по всему XML-документу, например, когда нужно извлечь значение каждого элемента.
Эту операцию и называют "обход дерева узлов" XML-документа.
В следующем примере в цикле просматриваются все дочерние узлы элемента <book> и выводятся их имена и значения:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var x, i ,xmlDoc;
var txt = "";
var text = "<book>" +
"<title>Everyday Italian</title>" +
"<author>Giada De Laurentiis</author>" +
"<year>2005</year>" +
"</book>";
parser = new DOMParser();
xmlDoc = parser.parseFromString(text,"text/xml");
// documentElement всегда содержит корневой узел
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>
Результат:
title: Everyday Italian
author: Giada De Laurentiis
year: 2005
Объяснение примера:
- Загружаем строку XML в переменную xmlDoc
- Получаем дочерние узлы корневого элемента
- Для каждого дочернего узла выводим имя узла и значение текстового узла.
Браузерные различия парсинга DOM
Все современные браузеры поддерживают спецификацию W3C DOM.
Однако между браузерами есть некоторые различия. И одно из важное отличие это то, как они обрабатывают пробелы и символы новой строки.
DOM – пробелы и символ новой строки
XML часто содержит символы новой строки или пробелов между узлами. Это часто случается, когда документ редактируется в простом редакторе, например в Блокноте.
Следующий пример (отредактированный в Блокноте) содержит CR/LF (символ новой строки) между каждой строкой и два пробела перед каждым дочерним узлом:
<book>
<title>Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
Internet Explorer 9 и более ранние версии этого браузера, в отличие от других браузеров, НЕ обрабатывают пробелы или новые строки как текстовые узлы.
В следующем примере будет выведено количество дочерних узлов у корневого элемента (из файла books.xml). IE9 и более ранние версии будут выводить 4 дочерних узла, а IE10 и более поздние версии и другие браузеры будут выводить 9 дочерних узлов:
function myFunction(xml) {
var xmlDoc = xml.responseXML;
x = xmlDoc.documentElement.childNodes;
document.getElementById("demo").innerHTML =
"Кол-во дочерних узлов: " + x.length;
}
PCDATA – Анализируемые символьные данные
Обычно парсеры XML анализируют/парсят весь текст в документе XML.
Когда XML-элемент парсится, также синтаксическому разбору подвергается и текст между XML-тегами:
<message>Этот текст также пропарсен</message>
Парсер делает это, потому что XML элементы могут содержать другие элементы, как в следующем примере, где элемент <name> содержит два других элемента (<first> и <last>):
<name><first>Bill</first><last>Gates</last></name>
и парсер разобьет такой элемент на подэлементы следующим образом:
<name>
<first>Bill</first>
<last>Gates</last>
</name>
Анализируемые символьные данные (PCDATA) — это термин, используемый для обозначения текстовых данных, которые будут подвергаться синтаксическому разбору парсером XML.
CDATA – (Неанализируемые) Символьные данные
Термин CDATA используется для обозначения текстовых данных, которые не должны подвергаться синтаксическому разбору парсером XML.
Такие символы, как "<" и "&" запрещено использовать в элементах XML.
Символ "<" вызовет ошибку, потому что парсер интерпретирует его как начало нового элемента.
Символ "&" вызовет ошибку, потому что парсер интерпретирует его как начало символьной сущности.
Некоторые текстовые данные, например, код JavaScript, содержат много символов "<" или "&". И чтобы избежать ошибок парсера, такие текстовые данные можно определить как CDATA.
Парсер игнорирует все, что находится внутри раздела CDATA.
Определение раздела CDATA начинается с "<! [CDATA [" и заканчивается "]]>":
<script>
<![CDATA[
function matchwo(a,b) {
if (a < b && a < 0) {
return 1;
} else {
return 0;
}
}
]]>
</script>
В приведенном выше примере все, что находится в разделе CDATA будет проигнорировано парсером.
Примечания к разделам CDATA:
- Раздел CDATA не может содержать строку "]]>". Вложенные разделы CDATA не допускаются.
- Строка "]]>", обозначающая конец раздела CDATA, не может содержать пробелов или разрывов строк.