jQuery与XML命名空间的区别以及Opera和Firefox之间的xhr.responseXML

时间:2009-10-21 15:25:18

标签: javascript jquery firefox opera xmlhttprequest

考虑一下:

<!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中可以正常工作。但是,除非我将查询从'atom\\:x'更改为'x',否则它在Opera中不起作用。在这种情况下,它适用于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的错误吗?如果是,哪个标准如此?
  3. 希望你能提供帮助:)

4 个答案:

答案 0 :(得分:3)

这不是Opera的错误。这是the correct behavior

  

在名称空间感知客户端中,元素类型选择器的名称部分(名称空间分隔符后面的部分,如果存在)将仅匹配元素的限定名称的本地部分。

在您的情况下,本地名称为xatom:x isn't even a legal local name in XML

此外,CSS中的namespace-prefixed type selector具有不同的语法,根本不使用冒号:

@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名称空间中。

答案 1 :(得分:2)

我已经在同一浏览器的不同版本中遇到过这种行为,据我记得当时我用FF和IE测试有问题的页面,所以我说这不是特定于Opera的错误。

我建议无论何时使用jQuery解析带有名称空间前缀的XML标记,都要查询带有和不带前缀的选择器。也就是说,而不是使用

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

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

我认为对于大多数情况来说这是一个可以接受的解决方法,它会确保您的结果是正确的,尽管有不当行为......

答案 2 :(得分:1)

我认为你应该说“atom:x”(没有反斜杠),并确保在html标签上有xmlns:atom =“http://www.w3.org/2005/Atom”声明在主要的html文件上,或以其他一些javascript知道的方式。

答案 3 :(得分:0)

很难说这是否是Opera中的错误,或者这是jQuery中的一个特定于Opera的错误。从它的声音来看,Opera没有正确地将命名空间添加到xhr文档dom中,这就是为什么jQuery不能查询atom:x并且还解释了为什么当你创建自己的jquery节点时,你得不到相同的结果。 / p>

我要做的第一件事就是尝试查看原子是否是xhr dom中定义的namspace。它应该按照定义返回你的原子ns,如果没有,这可能是一个歌剧bug。我不确定测试它的最佳方法,但也许:xhr.getElementByTagNameNS( "x" "http://www.w3.org/2005/Atom" );可以工作。

如果不这样做,Opera声称完全支持XML namespaces,那么,我会用jQuery打开一个错误请求,看看那是什么原因。

在其他方面,正如我在评论中提到的那样,我认为atom:x x查询{{1}}根本不是一个好主意。您也可以不使用命名空间,因为它会破坏目的。