【发布时间】:2017-09-22 07:07:35
【问题描述】:
我发现只有 Chrome 并没有给我在 XML 上使用 jQuery find(selector) 所期望的结果(来自 $.parseXML())。
考虑以下非常简化的代码 (https://jsfiddle.net/a504caa0/):
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
</head>
<body>
<script>
$(function ()
{
var xml =
'<?xml version="1.0"?>' +
'<DataSet>' +
' <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">' +
' <xs:element>' +
' </xs:element>' +
' </xs:schema>' +
'</DataSet>'
;
var xmlDoc = $.parseXML(xml)
var $docElm = $(xmlDoc.documentElement);
alert("> find('xs\\:schema').length=" + $docElm.find('> xs\\:schema').length);
alert("find('xs\\:schema').length=" + $docElm.find('xs\\:schema').length);
alert("> find('xs\\:schema').find('> xs\\:element').length=" + $docElm.find('> xs\\:schema').find('> xs\\:element').length);
alert("> find('xs\\:schema').find('xs\\:element').length=" + $docElm.find('> xs\\:schema').find('xs\\:element').length);
});
</script>
</body>
</html>
在 IE 11 或 Firefox 中运行它会为四个查询中的每一个报告一个 1 元素匹配,这是我所期望的。
但是,在 Chrome (57.0.2987.133) 中,查询 1 和 3 返回 1 个元素,但查询 2 和 4 返回 0 个元素。这意味着:
$xml.find('> selector')
正在寻找匹配项,而
$xml.find('selector')
没有找到匹配项。换句话说,如果查询直接子元素,它会找到一个元素,但如果查询任何后代,它会说它不存在!
我不知道这是否只是一个 XML 问题,或者是否需要使用 xs\\: 命名空间是一个问题。
在现实生活中,XML 更大更深,有时我需要查询任何后代,而不仅仅是直系子代。解决方案不能仅仅通过更改上述查询(例如将多个find()s 合并为一个或使用children())来工作,它必须在没有前导> 的情况下一般在find() 上工作/解释Chrome 行为。
编辑:我刚刚尝试从 XML 中删除所有 xs: 并从 find() 中删除 xs\\:,果然它现在返回 Chrome 下的 1 个元素。因此,看起来这是find() 问题中的 XML 命名空间。当然,在现实生活中我无法做到这一点。似乎 Chrome 可以找到具有命名空间前缀的直接子代,但在涉及泛型血统时却不能?是否有可接受的解决方法?
【问题讨论】:
-
FWIW 如果
xs是唯一的命名空间,则无需在find中指定它。 -
但根据示例,您可以看到
<Dataset>位于默认命名空间中,而不是xs之一。如果你在我的 JSFiddle 中删除选择器的 `xs:\\`,你会发现什么都找不到。
标签: jquery google-chrome parsexml