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

考虑一下:

 XML-problem   $(function() { $('

').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'); }); });

加载文档时,此脚本应加载text.xml。 text.xml看起来像这样:

  Text  

加载此文件后, atom:x -node的文本内容将附加到文档中。 我可以在浏览器窗口中看到“文本”。

这在Firefox中可以正常工作。 但是,除非我将查询从'atom\\:x'更改为'atom\\:x' ,否则它在Opera中不起作用。 在这种情况下,它适用于Opera,但不适用于Firefox。

我发现了一种解决方法,即将查询更改为'atom\\:x, x' ,但我更愿意深入研究。


现在有趣的转折:我可以直接内联xml而不是通过更改从XHR获取它

 var xml = $(xhr.responseXML); 

 var xml = $('Text'); 

在这种情况下, 'atom\\:x'的查询将在两个浏览器中提供所需的结果,而'x'将在两个浏览器中都不会产生任何结果。

事实上,这在Opera中的工作方式不同,这让我得出结论,前者的行为是Opera中的一个错误。 这是一个合理的结论吗? 我在哪里可以指出描述它应该如何工作的标准?


结论:

  1. 这个问题的替代解决办法有哪些? 有没有比我找到的更好?
  2. 这是Opera中的一个错误吗? 如果是的话,哪个标准是这样说的?

希望你能帮忙:)

这不是Opera中的错误。 这是正确的行为 :

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

在您的情况下,本地名称是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中你得到http://www.w3.org/2005/Atom x元素http://www.w3.org/2005/Atom命名空间。

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

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

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

尝试

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

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

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

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

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

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

在其他方面,正如我在评论中提到的那样,我认为查询atom:x by x根本不是一个好主意。 您也可以不使用名称空间,因为它违背了目的。