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中的一个错误。 这是一个合理的结论吗? 我在哪里可以指出描述它应该如何工作的标准?
结论:
- 这个问题的替代解决办法有哪些? 有没有比我找到的更好?
- 这是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
根本不是一个好主意。 您也可以不使用名称空间,因为它违背了目的。