Search code examples
jquerygoogle-chromeparsexml

Chrome incorrect jQuery find() on XML result


I am finding that Chrome, only, is not giving me the result I expect using a jQuery find(selector) on XML (from $.parseXML()).

Consider the following much simplified code (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>

Running this in IE 11 or Firefox reports a 1-element match for each of the four queries, which is what I expect.

However, in Chrome (57.0.2987.133) queries 1 & 3 return 1 element but queries 2 & 4 return 0 elements. This means that:

$xml.find('> selector')

is finding a match, while

$xml.find('selector')

is not finding a match. In other words, if queried for a direct child it finds an element, but if queried for any descendant it says it's not there!

I do not know whether this is an XML-only issue, or whether the need to use the xs\\: namespace is a problem.

In real life the XML is bigger and deeper, and there are times I need to query for any descendant, not just direct children. The solution must not just work by changing the above queries (e.g. conglomerating multiple find()s into one or using children()), it must work/explain the Chrome behaviour generically on find() without a leading >.

EDIT: I just tried removing all xs: from the XML and xs\\: from the find(), and sure enough it now returns 1 element under Chrome. So, it looks like this is an XML-namespace in find() issue. Of course, I cannot do that in real life. It seems Chrome can find direct children with namespace prefix but not when it involves a generic descent? Is there an acceptable workaround?


Solution

  • I reported this bug for chromium at https://bugs.chromium.org/p/chromium/issues/detail?id=738372.

    As per response https://bugs.chromium.org/p/chromium/issues/detail?id=738372#c10 there, this bug became fixed in Chrome #60. Chrome now correctly searches XML with namespaces, delivering the same results as Firefox/IE 11.