Парсинг XML файла с помощью jQuery

Этой статьей хочу начать рубрику “Методики” в которой буду рассказывать о своем опыте при решении различных задач.

Часто, в проектах, стоит задача формирования HTML кода документа из стороннего файла с помощью AJAX, и зачастую данные в этих файлах хранятся в XML. Поэтому сегодня хочу рассказать как сделать парсинг XML документа с помощью jQuery.

Что бы описать методику парсинга я выбрал пример наиболее часто встречаемый в проектах, а также который вы встречали не однократно на различных сайтах – это появление подсказок при наборе текста в поисковых запросах. Т.е. перед нами лежит задача написать JavaScript код который отправляет данные набора серверу, который, в свою очередь, формирует XML результат. Парсинг XML документа и формирование на его основе HTML элементов для отображения пользователю.

Часть которая происходит на сервере я описывать не буду, т.к. не являюсь хорошим специалистом в серверных языках и базах данных. Но все же представить себе сценарий могу – сервер принимает данные ввода текста и по определенному алгоритму выбирает из базы данных соответствующие результаты, после чего формирует XML документ.

Для окончательного осознания того, что мы должны сделать – рассмотрим окончательный вариант нашего скрипта. Введите текст в текстовое поле. Т.к. кода для серверной части у меня нет я создал статический XML файл который будет выводится в HTML.

Результат который мы должны получить:

Вы можете открыть пример в новом окне или скачать локальную версию.

Структура HTML документа:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Парсинг XML с помощью jQuery</title>
        <link rel="stylesheet" type="text/css" href="css/all.css" />
        <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
        <script type="text/javascript" src="js/jquery.main.js"></script>
    </head>
    <body>
        <form action="inc/result.xml">
            <div id="main-container">
                <input type="text" id="textArea" />
                <ul id="resultHolder">
                    <li><a href="#">&nbsp;</a></li>
                </ul>
            </div>
        </form>
    </body>
</html>

Для примера нам понадобится текстовое поля для запроса от пользователя и элемент вывода результата, в данном случае это список.

Структура XML документа:

<?xml version="1.0" encoding="utf-8"?>
<result>
    <item>markup-javascript.com</item>
    <item>markup</item>
    <item>javascript</item>
    <item>jQuery</item>
    <item>mootools</item>
    <item>prototype</item>
    <item>XHTML</item>
    <item>CSS</item>
    <item>XML</item>
</result>

Структуру я выбрал наиболее простую для понимания и обработки JSом. В теге <result> находится список результата.

Самая интересная часть :) Разрабатываем JavaScript код:

Для оптимальной работы скрипта создадим ссылки на объекты и добавим событие к текстовому полю.
Адрес для отправки запроса серверу возьмем из атрибута action тега form.

$(document).ready(function(){
    // объявляем ссылки на объекты текстового поля и результата
    var _textArea = $('#textArea');
    var _resultHolder = $('#resultHolder');
    var _resultEl = $('a',_resultHolder);
   
    // найдем адрес для запроса к серверу
    var _url = _textArea.parents('form').attr('action');

    // добавляем событие на изменение текста
    _textArea.keypress(function(){
        // функция отрабатываемая при нажатии клавиш
       
    });
});

При печатании текста в текстовом поле будет происходить отправка набранных символов на сервер, при помощи стандартных функций ajax запросов для jQyery.

$.ajax({
    url: _url, // адрес полученный в атрибуте action
    dataType:'xml', // тип данных
    success: function(xmlData){
       // при позитивном результате запроса в переменной xmlData хранится наш XML документ
    }
});

Но не все так гладко, на этом моменте как всегда вмешивается Internet Explorer. В переменной xmlData IE не может распознать XML объекты. Тогда, для правильной работы скрипта, мы должны модифицировать код.
В параметре dataType для IE зададим строковый тип данных, а полученный результат при помощи ActiveX преобразуем в XML документ. В итоге AJAX запрос будет выглядеть так:

$.ajax({
    url: _url,
    dataType: (jQuery.browser.msie) ? 'text' : 'xml', // проверка IE и выбор типа данных
    success: function(xmlData){
        var data;
        if ( typeof xmlData == 'string') {
            // если это IE то создаем ActiveX объект и приобразуем строковую переменную в XML
            data = new ActiveXObject( 'Microsoft.XMLDOM');
            data.async = false;
            data.loadXML( xmlData);
        } else {
            data = xmlData;
        }

    }
});

На данном шаге мы получаем вполне кроссбраузерный код для получение XML данных, теперь дело осталось за малым – получить данные из XML и сгенерировать HTML код. Для этого в функцию success AJAX запроса добавим следующий код:

// генерация HTML кода
var _result = '';
$('item',data).each(function(i, _item){
// из каждого тега item выберем текстовую переменную
// и добавим к общему результату сформировав список.
    _result += '<li><a href="#">'+$(_item).text()+'</a></li>';
});
// вывод данных пользователю
_resultHolder.html(_result).slideDown(300);

В итоге наш код можно считать почти готовым для использования… но конечно сюда можно добавить некоторые штрижки. Например проверку на корректность вводимых символов или какие либо нюансы при отображении результата, но я решил не замарачиваться ведь основную идею я вам изложил. Добавлю лишь функцию для выбора из списка результат и добавление его в текстовое поле.

Окончательный вид функции:

$(document).ready(function(){
    // объявляем объекты текстового поля и результата
    var _textArea = $('#textArea');
    var _resultHolder = $('#resultHolder');
    var _resultEl = $('a',_resultHolder);
   
    // найдем адрес для запроса к серверу
    var _url = _textArea.parents('form').attr('action');

    // добавляем событие на изменение текста
    _textArea.keypress(function(){
        // формируем AJAX запрос
        $.ajax({
            url: _url,
            dataType: (jQuery.browser.msie) ? 'text' : 'xml', // проверка IE и выбор типа данных
            success: function(xmlData){
                var data;
                if ( typeof xmlData == 'string') {
                    // если это IE то создаем ActiveX объект и приобразуем строковую переменную в XML
                    data = new ActiveXObject( 'Microsoft.XMLDOM');
                    data.async = false;
                    data.loadXML( xmlData);
                } else {
                    data = xmlData;
                }
            // генерация HTML кода
            var _result = '';
            $('item',data).each(function(i, _item){
                _result += '<li><a href="#">'+$(_item).text()+'</a></li>';
            });
            _resultHolder.html(_result).slideDown(300);
            }
        });
    });
    // выбор результата
    _resultEl.live('click',function(){
        _textArea.val($(this).text());
        _resultHolder.slideUp(300);
        return false;
    });
});

Надеюсь данная статья поможет Вам в реализации ваших проектов. хотелось бы услышать от вас вопросы, в реализации различных задач, наиболее интересные будут рассмотрены в этом блоге.

Tags: , ,

Воскресенье, Апрель 5th, 2009 JavaScript, jQuery, Методики

17 Коментариев to Парсинг XML файла с помощью jQuery

  • Александр:

    Хорошая статья, как раз в тему…всё это здорово, а как достать содержимое файла если скрипт его прячет?
    как здесь: http://ifolder.ru/11577181

  • А зачем вам это содержимое :) ?
    Ну во первых раз прячет значит так захотел разработчик…
    а во вторых скрипт может указывать и прямой путь к файлу, но не всегда его можно посмотреть потому что он отображается с определенными условиями которые передает браузер.

  • Oleg:

    Спасибо за статью! Здорово помогла в борьбе с експлорером )

  • Андрей:

    в Вашему мануалу делал парсинг..

    разрабатываю на опере..

    проблема в следующем:
    формирую хмл такой:

    <?xml version=”1.0″ encoding=”windows-1251″?>

    <content count=”1″>
    <sim sn=”57964″ tel=”27″ tarif=”1″ own=”2″ />
    </content>

    его получаю,
    распарсивает:
    $(‘sim’,data).each(function(i, _sim){ …

    а вот кол-во вытащить не могу из :
    var count = $(“content”,data).attr(“count”);
    alert(count);

    на алерт – говорит undefined

    может чето не так?

  • Написанный код вроде верен…
    я так понимаю count=”1″ это количество sim? попробуйде количество выбирать так $(’sim’,data).length

  • Андрей:

    а вот если парсить

    $(’content’,data).each(function(i, _c)
    {
    $(“div#count”).html( $(_c).attr(“count”) );
    }

    тогда распарсивает..

    jquery случайно не рассматривает даже единичные елементы как множества в xml?

  • Денис:

    А если мне надо сделать аякс запрос к пхп файлу, в котором надо сгенерить xml и отдать ее яваскрипту?
    Не получается. При выводе в пхп файле указываю также заголовок “application/xml”.

  • Скорее всего вы неправильно формируете xml файл, поэтому джс не может его нормально распарсить.
    Каким бы методом вы не формировали xml… других причин быть не может

  • Спасибо, очень вовремя нашёл, а то бы мучился ещё долго, не понимая, почему не работают селекторы на не HTML тегах. :( Ну ie, еееее. :(

  • PlayText:

    loadXML для эксплорера разве не надо поправить просто на load????

  • Может быть роли никакой и не сыграет… просто loadXML более наглядно отображает пример.

  • Dmitry:

    А вот как преобразовать переменную (в которой содержится xml данные) в подходящий тип данных(XML)? Ведь при AJAX запросе это происходит автоматически.

  • Дмитрий:

    вместо записи
    var count = $(“content”,data).attr(“count”);
    скорее будет
    var count = $(“content”,data).eq(0).attr(“count”);

  • Артем:

    В данный момент разрабатываю сервис по проверки целостности ссылок на странице. Необходимо использовать javascript для парсинга ссылок со страницы. Не подскажи те ли как это лжше сделать и что почитать, так как до этого занимался php в js новичок

  • Спасибо за тему. Буду раскуривать парсинг непосредственно XML, а то привык из AJAX-запроса возвращать уже готовый HTML-код. А это не есть хорошо, много мусора передается, с XML, надеюсь, будет проще.

    А что думаете о JSON?

  • Нижнее подчёркивание в переменных очень нечитабельно, или есть какая-то функциональная особенность у переменных типа var _textArea = $(‘#textArea’); в отличии от var textArea = $(‘#textArea’); ???

  • Оставить сообщение

    Rotaban.ru - биржа банерной рекламы