【问题标题】:Difference in jQuery with XML namespace and xhr.responseXML between Opera and FirefoxOpera 和 Firefox 之间带有 XML 命名空间和 xhr.responseXML 的 jQuery 的区别
【发布时间】:2010-12-08 18:23:39
【问题描述】:

考虑一下:

<!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-node 的文本内容将附加到文档中。我可以在浏览器窗口中看到“文本”。

这在 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 中的错误吗?如果是,哪个标准是这样说的?

希望你能帮忙:)

【问题讨论】:

  • 看起来像一个注意到的错误。 thompson-web.blogspot.com/2009/03/…dev.jquery.com/ticket/155
  • @Stefan:所以,无论浏览器如何,jQuery 都应该在只查询“x”时给我结果?
  • 你为什么使用load?加载应该是 html,而不是 xml。它是否适用于ajaxget
  • 我在实际应用中实际使用ajax。我为这个示例选择了load 以使其更小。无论如何,它对观察到的行为没有任何影响。
  • @brianpeiris:我看到您将 XML 文档作为 text/html 提供。 IIRC,这导致 XHR 将其视为文本,而不是 XML。这可能是我们两个设置之间存在差异的原因。

标签: javascript jquery firefox opera xmlhttprequest


【解决方案1】:

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

【讨论】:

  • 那将工作。冒号是jquery中的特殊字符,必须转义。
【解决方案2】:

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

我要做的第一件事是尝试查看 atom 是否是 xhr dom 中已定义的命名空间。它应该按照定义返回您的原子 ns,如果不是,这可能是一个歌剧错误。我不确定测试这个的最佳方法,但也许:xhr.getElementByTagNameNS( "x" "http://www.w3.org/2005/Atom" ); 会起作用。

如果做不到这一点,Opera 声称完全支持XML namespaces,但是,我会用 jQuery 打开一个错误请求,看看你在哪里。

在其他方面,正如我在评论中回避的那样,我认为通过 x 查询 atom:x 根本不是一个好主意。你最好不要使用命名空间,因为它违背了目的。

【讨论】:

  • 感谢您的提示。很遗憾,我无法立即对其进行测试...我会再回复您。
【解决方案3】:

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

我建议,每当您使用 jQuery 解析带有命名空间前缀的 XML 标记时,您都可以查询带有和不带有前缀的选择器。也就是说,而不是使用

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

试试

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

我认为这在大多数情况下都是可接受的解决方法,它可以确保您的结果是正确的,尽管存在不当行为...

【讨论】:

    【解决方案4】:

    这不是 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 中,您会在 http://www.w3.org/2005/Atom 命名空间中获得 x 元素。

    【讨论】:

      猜你喜欢
      • 2020-08-21
      • 2012-08-12
      • 2020-10-21
      • 2018-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-20
      • 2011-03-27
      相关资源
      最近更新 更多