Разбор XML с CDATA с помощью JQuery

Изменить: я пропустил две вещи здесь. Отсутствие "Content-Type:text/xml" в заголовке, возвращаемом вызовом AJAX, не позволяло JQuery рассматривать возвращенные данные как документ. После того, как это было обработано правильно, этот код анализируется правильно и выводит только индекс и имя проекта.

$("a.getprojects").click(function(d){
  d.preventDefault();
  var api_token = $("#token").val();
  var form_fbod = $("#fbod").val();
  $.post("fbinfo.php", {fbod: form_fbod, token: api_token, cmd : 'listProjects', extra:''}, function(returned_xml) {
    var output = '';
    $(returned_xml).find("project").each(function(){
      var project = $(this);
      output += project.find("ixProject").text();
      output += " ";
      output += project.find("sProject").text();
      output += "\n";
    });
    $("#output").val(output);
  });
});

Оригинал: я получаю удовольствие, используя FogBugz API и JQuery, чтобы собрать то, что, на мой взгляд, будет классным маленьким инструментом, но я столкнулся с ограничением JQuery. Теги CDATA, кажется, путают это.

Вот код, который я использую:

  $("a.getprojects").click(function(d){
    d.preventDefault();
    var api_token = $("#token").val();
    var form_fbod = $("#fbod").val();
    $.post("fbinfo.php", {fbod: form_fbod, token: api_token, cmd : 'listProjects', extra:''}, function(xml) {
      var output = xml;
      $(xml).find("project").each(function(){
        var project = $(this);
        output += "\n\n";

        output += project.html();

      });
      $("#output").val(output);

    });
  });

И вот вывод, который я получаю:

<?xml version="1.0" encoding="UTF-8"?><response>
    <projects>
<project>
<ixProject>2</ixProject>
<sProject><![CDATA[Inbox]]></sProject>
<ixPersonOwner>2</ixPersonOwner>
<sPersonOwner><![CDATA[Rich]]></sPersonOwner>
<sEmail><![CDATA[rich@example.com]]></sEmail>
<sPhone></sPhone>
<fInbox>true</fInbox>
<ixGroup>1</ixGroup>
<iType>1</iType>
<sGroup><![CDATA[Internal]]></sGroup>
</project>

<project>
<ixProject>1</ixProject>
<sProject><![CDATA[Sample Project]]></sProject>
<ixPersonOwner>2</ixPersonOwner>
<sPersonOwner><![CDATA[Rich]]></sPersonOwner>
<sEmail><![CDATA[rich@example.com]]></sEmail>
<sPhone></sPhone>
<fInbox>false</fInbox>
<ixGroup>1</ixGroup>
<iType>1</iType>
<sGroup><![CDATA[Internal]]></sGroup>
</project>
</projects>
</response>

<ixproject>2</ixproject>
<sproject></sproject>
<ixpersonowner>2</ixpersonowner>
<spersonowner></spersonowner>
<semail></semail>
<sphone></sphone>
<finbox>true</finbox>
<ixgroup>1</ixgroup>
<itype>1</itype>
<sgroup></sgroup>

<ixproject>1</ixproject>
<sproject></sproject>
<ixpersonowner>2</ixpersonowner>
<spersonowner></spersonowner>
<semail></semail>
<sphone></sphone>
<finbox>false</finbox>
<ixgroup>1</ixgroup>
<itype>1</itype>
<sgroup></sgroup>

Казалось бы, синтаксический анализ XML, свойственный JQuery, отбрасывает содержимое элементов CDATA. FogBugz помещает большинство наших строковых данных в теги CDATA, потому что мы разрешаем специальные символы и знаки препинания в большинстве мест. Заключение вывода в теги CDATA позволяет нам быть относительно уверенными в том, что мы отправляем верные данные через наш API. PHP-разбор XML работает просто отлично. Мои онлайн-исследования приводят к тому, что несколько человек жалуются на это, но не так много работы. С расширяемостью JQuery я бы подумал, что там что-то есть. Кто-нибудь еще достиг этого?

2 ответа

Решение

Казалось бы, разбор XML, который является родным для JQuery

Там нет синтаксического анализа XML нативно для jQuery. Он просто использует стандартное свойство XMLHttpRequest.responseXML, чтобы получить XML DOM для ответа.

отбрасывает содержимое элементов CDATA

С каким Content-Type вы отправляете ответ? Потому что я подозреваю, что он вообще не анализируется как XML. В этом случае jQuery будет передавать вам строку документа вместо XML DOM.

Затем, когда вы вызываете "$(xml)", он будет создавать содержимое документа из этой строки (*) - анализируется как HTML, а не XML. В HTML нет такого понятия, как раздел CDATA, поэтому браузеры могут отбрасывать их или рассматривать как комментарии.

Я подозреваю, что это, потому что "project.html()" не должен работать, когда документ в формате XML. html () просто возвращает то же самое, что и стандартное свойство innerHTML (**), которое работает только для документов HTML; он не определен для элементов XML.

Заключение вывода в теги CDATA позволяет нам быть относительно уверенными в том, что мы отправляем верные данные через наш API.

Что ж, "относительно": если ваши данные содержат "]]>", вы все равно проигрываете.

(*: Я никогда не понимал, когда jQuery чувствует необходимость объединить создание фрагментов документа и выбор CSS в одну и ту же функцию. Это совершенно разные операции, которые вы не хотите запутывать, как, возможно, произошло здесь.)

(**: На самом деле, он пытается сначала отфильтровать пользовательские атрибуты jQuery, используя регулярное выражение. К сожалению, поскольку регулярное выражение не может анализировать HTML, он с радостью отфильтрует допустимые части вашего текста, которые выглядят как атрибуты HTML. К сожалению, не один из Более красивые части jQuery.)

На самом деле в jquery теперь есть xml-анализатор, который должен решить вашу проблему. $.parseXML (xml) http://api.jquery.com/jQuery.parseXML/

Другие вопросы по тегам