Side navigation
#1826 closed feature (wontfix)
Opened October 19, 2007 12:41PM UTC
Closed April 16, 2011 09:29PM UTC
Last modified October 26, 2012 02:07PM UTC
namespaces handling for XMLs
Reported by: | Orange | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | core | Version: | 1.2.1 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
Actual jQuery does return wrong results as soon as the user uses namespaces in an xml, because IE does not handle namespaces the same way as other browsers does.
In jQuery, this concerns the use of "nodeName" which returns "prefix:tagName" instead of "tagName". This concerns the following lines in jQuery-1.2.1.js which should be corrected with the following, in order to hide namespaces :
line 1260:
c.nodeName.replace(/^.*:/,'').toUpperCase()instead of
c.nodeName.toUpperCase()
line 1284:
n.nodeName.replace(/^.*:/,'').toUpperCase()instead of
n.nodeName.toUpperCase()
An other element that causes wrong behavior is "getElementsByTagName" which has to be used in IE with "prefix:tagName". This could be corrected by the following change :
line 1362:
r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));should be changed in :
// getElementsByTagName will not work with IE & namespaces var retour = []; if (jQuery.browser.msie && (ret[i].namespaces!=null) && (ret[i].namespaces.length>0)) { retour = jQuery.merge(retour,ret[i].getElementsByTagName(tag)); for(var nsIndex = 0; nsIndex<ret[i].namespaces.length; nsIndex++) { var ns = "xmlns:ns='"+ret[i].namespaces(nsIndex)+"'"; ret[i].setProperty("SelectionNamespaces", ns); var IeReturn = ret[i].selectNodes("ns:"+tag); retour = jQuery.merge(retour, IeReturn); } } else { retour = ret[i].getElementsByTagName(tag); } r = jQuery.merge(r, retour);
Changes have been tested on IE6/7, Mozilla, Safari & Opera. They may be easier way to perform it, but this one works.
Attachments (0)
Change History (8)
Changed October 19, 2007 01:58PM UTC by comment:1
Changed June 06, 2008 05:23AM UTC by comment:2
This is similar to the solution suggested in ticket 155 but this avoids the potentially slow string searching that does with regular expressions. However, his only works when the context is the document node (IXMLDocument2). If the context is a node from within the document (IXMLDOMElement) then this fails because IXMLDOMElement does not have a namespaces property. In addition, the XPath used in selectNodes returns all matching nodes in the document rather than descendants of the context node.
To get around these issues you need to look at the ownerDocument and tweak the XPath. Something like this:
// getElementsByTagName will not work with IE & namespaces var tags = []; if (jQuery.browser.msie && ret[i].xml !== undefined && tag != '*') { var od = (ret[i].ownerDocument) ? ret[i].ownerDocument : ret[i]; var ns = od.namespaces; if ((ns!=null) && (ns.length>0)) { for (var nsIndex = 0; nsIndex<ns.length; nsIndex++) { od.setProperty("SelectionNamespaces", "xmlns:ns='" + ns(nsIndex) + "'"); var IeReturn = ret[i].selectNodes(".//ns:"+tag); tags = jQuery.merge(tags, IeReturn); } } } tags = jQuery.merge(tags,ret[i].getElementsByTagName(tag)); r = jQuery.merge(r, tags);
This is really only a partial solution to the issue. What's really needed is a way to specify a namespace in the selector. I've seen a suggestion that the | character be used for that. So, "ns|tag" would return all tags of the form <ns:tag>. But the prefix should not be hard coded in a selector. The whole point of it is that the prefix should be able to be changed to avoid conflicts without affecting code that processes the document.
So, either we include the whole namespace URL in the selector, or we have a way to map another namespace prefix to the URI:
.find(selector, context, nsPrefix, nsURI)
(for example)
Changed June 06, 2008 05:48AM UTC by comment:3
And, while I think of it, the first two fixes (adding the replace to the nodeName comparisons in the section that handles child selectors) more-or-less get the job done, but they also have a problem. XML is case sensitive. Converting everything to uppercase to do a comparison might be appropriate for HTML documents but not for XML documents.
Changed November 13, 2010 07:20PM UTC by comment:5
status: | new → open |
---|
This ticket has been open for so long because it appears to be very difficult to solve.
https://bugzilla.mozilla.org/show_bug.cgi?id=414612
For XML docs we'd need to use getElementsByTagNameNS according to that.
Also, Sizzle's first resort of querySelectorAll doesn't support namespaces but it should throw an exception:
Changed April 16, 2011 09:29PM UTC by comment:7
milestone: | 1.2.2 |
---|---|
resolution: | → wontfix |
status: | open → closed |
Honestly, I don't think that this is something that we're going to ever implement. Especially considering that at this point we don't even use querySelectorAll on XML documents. Sorry!
Error in suggested solution for line 1362 :
should be