В этой статье мы рассмотрим клиентский JavaScript на основе XML, который считывает данные из внешнего XML-файла, просматривает данные XML и отображает их в древовидном формате.
Для этого я буду использовать объект ActiveX XMLDOM, встроенный в Microsoft Internet Explorer.
Рассмотрим следующий XML-файл:
Сценарий, который мы хотим сделать, это отобразить приведенные выше данные XML следующим образом:
- личный: Личные данные
- пол: мужской
- сайты: сайты
- ws1: http://www.sitepoint.com
- ws2: http://sitepointforums.com
Алгоритм
Вот процесс, который мы будем использовать для достижения этой цели:
- Прочитайте файл XML
- Укажите переменную tree на первый узел (тег XML) данных XML.
- Если узел имеет дочерние узлы:
- Распечатать "<ul> <li>";
- Для каждого дочернего узла traverse (tree.childNodes (nodeNum))
- Распечатать "</ li> </ ul>";
- Если у узла нет дочернего элемента:
- Напечатайте значение узла.
Сценарий и объяснение
Давайте посмотрим на скрипт:
var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
Приведенный выше код создает новый экземпляр объекта ActiveX Microsoft.XMLDOM.
function loadXML(xmlFile) { xmlDoc.async="false"; xmlDoc.onreadystatechange=verify; xmlDoc.load(xmlFile); }
Функция loadXML()
используется для загрузки определенного XML-файла. Эта функция ссылается на функцию verify()
, которая выглядит следующим образом:
function verify() { if(xmlDoc.readyState!=4) return false; }
Загрузка файла XML происходит в 5 этапов:
- 0 - объект не инициализирован
- 1 - Загрузка объекта загружает данные
- 2 - загруженный объект загрузил данные
- 3 - Данные с объекта могут быть обработаны с
- 4 - Объект полностью инициализирован
Доступ к состоянию загрузки XML-файла можно получить через свойство readyState readyState
: если файл (объект) не инициализирован, xmlDoc.readyState
вернет 0 и т. Д. Таким образом, с помощью функции loadXML()
мы можем проверить состояние загрузки документа XML - очевидно, мы не хотим использовать частично или полностью неинициализированный объект.
Теперь давайте посмотрим на функцию, выполняющую обход данных XML, traverse()
:
function traverse(tree) { if(tree.hasChildNodes()) { document.write('<ul><li>'); document.write('<b>'+tree.tagName+' : </b>'); var nodes=tree.childNodes.length; for(var i=0; i<tree.childNodes.length; i++) traverse(tree.childNodes(i)); document.write('</li></ul>'); } else document.write(tree.text); }
Функция traverse()
- это рекурсивная функция, которая принимает узел в качестве аргумента.
Как объяснялось ранее в алгоритме, функция сначала проверяет, есть ли у узла дочерние элементы. Если у узла есть дочерние элементы, необходимые отступы реализуются с использованием списков HTML (теги <ul>
, <li>
). Далее для каждого из дочерних узлов этого узла вызывается функция traverse()
(рекурсивно) с аргументом в качестве этого дочернего узла.
Если узел (аргумент, переданный traverse()
) не имеет дочерних узлов, функция печатает значение, содержащееся в этом узле (теге). Таким образом, создается древовидная структура для файла XML. Теперь давайте посмотрим на initTraverse()
:
function initTraverse(file) { loadXML(file); var doc=xmlDoc.documentElement; traverse(doc); }
Функция initTraverse()
принимает имя файла XML в качестве аргумента. Эта функция сначала загружает файл XML, устанавливает переменную doc в корневой узел данных XML, а затем пересекает данные XML с помощью функции traverse()
с аргументом в качестве корневого узла (т. doc
).
Эта функция вызывается, когда вы хотите сгенерировать древовидную структуру XML-файла.
Весь приведенный выше код может быть размещен во внешнем файле .js. Следующий код должен быть размещен в месте, где должна быть сгенерирована древовидная форма файла XML:
initTraverse("anyXMLfile.xml");
Вот полный сценарий.
<script language="JavaScript"> var xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); function loadXML(xmlFile) { xmlDoc.async="false"; xmlDoc.onreadystatechange=verify; xmlDoc.load(xmlFile); } function verify() { if(xmlDoc.readyState!=4) return false; } function traverse(tree) { if(tree.hasChildNodes()) { document.write('<ul><li>'); document.write('<b>'+tree.tagName+' : </b>'); var nodes=tree.childNodes.length; for(var i=0; i<tree.childNodes.length; i++) traverse(tree.childNodes(i)); document.write('</li></ul>'); } else document.write(tree.text); } function initTraverse(file) { loadXML(file); var doc=xmlDoc.documentElement; traverse(doc); } </script>