Разница в jQuery с пространством имен XML и xhr.responseXML между Opera и Firefox - PullRequest
5 голосов
/ 21 октября 2009

Учтите это:

<!DOCTYPE HTML>
<html><head><title>XML-problem</title>

<script src="jquery-1.3.2.min.js" type="text/javascript"></script>

<script type="text/javascript">

$(function() {
    $('<p/>').load("text.xml", function(responseText, textStatus, xhr) {
        var xml = $(xhr.responseXML);
        var x_txt = xml.find('atom\\:x').text();
        $(this).text(x_txt).appendTo('#container');
    });
});

</script>

</head><body><div id="container" /></body></html>

Этот скрипт должен загружать text.xml после загрузки документа. text.xml выглядит так:

<xml xmlns:atom="http://www.w3.org/2005/Atom">
    <atom:x>Text</atom:x>
</xml>

Когда этот файл загружен, текстовое содержимое узла atom:x добавляется к документу. Я вижу текст в моем окне браузера.

Это работает как и ожидалось в Firefox. Тем не менее, он не работает в Opera, если я не изменю запрос с 'atom\\:x' на 'x'. В этом случае он работает в Opera, но не в Firefox.

Я нашел обходной путь, а именно изменив запрос на 'atom\\:x, x', но я бы предпочел разобраться с этим.


Теперь о забавном повороте: я могу встроить xml напрямую, вместо того чтобы получать его из XHR, изменив

var xml = $(xhr.responseXML);

в

var xml = $('<xml xmlns:atom="http://www.w3.org/2005/Atom"><atom:x>Text</atom:x></xml>');

В этом случае запрос 'atom\\:x' даст желаемый результат в обоих браузерах, и просто 'x' не даст результата в обоих браузерах.

Тот факт, что в Opera это работает иначе, заставляет меня заключить, что прежнее поведение является ошибкой в ​​Opera. Это разумный вывод? Где я могу указать на стандарт, который описывает, как это должно работать?


В заключение:

  1. Каковы альтернативные способы решения этой проблемы? Лучше, чем тот, который я нашел?
  2. Это ошибка в Opera? Если да, то какой стандарт говорит об этом?

Надеюсь, вы можете помочь:)

Ответы [ 4 ]

3 голосов
/ 09 ноября 2009

Это не ошибка в Опере. Это правильное поведение :

В клиенте, поддерживающем пространство имен, часть имени селекторов типа элемента (часть после разделителя пространства имен, если он присутствует) будет соответствовать только локальной части квалифицированного имени элемента.

В вашем случае локальное имя x, а atom:x даже не является допустимым локальным именем в XML .

Более того, селектор типа с префиксом пространства имен в CSS имеет другой синтаксис, который вообще не использует двоеточие:

@namespace atom url(http://www.w3.org/2005/Atom);
atom|x { color: blue }

Ваш синтаксис основывается на причуде, введенной анализаторами HTML в пользовательских агентах, не подозревающих о пространстве имен.

HTML-анализатор "съедает" двоеточие как часть имени тега, и вы получаете элемент atom:x в пространстве имен по умолчанию, который соответствует селектору atom\:x, но в XML вы получаете элемент x в пространстве http://www.w3.org/2005/Atom.

2 голосов
/ 06 ноября 2009

Я уже сталкивался с таким поведением в разных версиях одного и того же браузера и, насколько я помню, в то время, когда я тестировал проблемную страницу с помощью FF и IE, поэтому я бы сказал, что это не специфичная для Opera ошибка.

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

var x_txt = xml.find('atom\\:x').text();

попробовать

var x_txt = xml.find('atom\\:x, x').text();

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

1 голос
/ 05 ноября 2009

Я думаю, вы должны сказать «atom: x» (без обратной косой черты) и обязательно иметь объявление xmlns: atom = "http://www.w3.org/2005/Atom" либо в теге html основного файла html, либо каким-либо другим способом известный за JavaScript.

0 голосов
/ 05 ноября 2009

Трудно сказать, является ли это ошибкой в ​​опере, или это ошибка в jQuery, которая специфична для Opera. Судя по всему, Opera неправильно добавляет пространство имен в документ xhr dom, и поэтому jQuery не может запрашивать atom: x, а также объясняет, почему, когда вы создаете свой собственный узел jquery, вы не получаете такие же результаты.

Первое, что я хотел бы сделать, это попытаться выяснить, является ли атом определенным пространством в xhr dom. Он должен вернуть ваши атомы как определено. Если нет, то это, вероятно, ошибка в опере. Я не уверен, что лучший способ проверить это, но, возможно: xhr.getElementByTagNameNS( "x" "http://www.w3.org/2005/Atom" ); будет работать.

Если это не удастся, Opera заявляет, что полностью поддерживает пространства имен XML , однако я открою запрос об ошибке с помощью jQuery и выясню, откуда это у вас.

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

...