Skip to main content

Bug Tracker

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 Orange comment:1

Error in suggested solution for line 1362 :

var IeReturn = ret[i].selectNodes("ns:"+tag);
should be
var IeReturn = ret[i].selectNodes("//ns:"+tag);

Changed June 06, 2008 05:23AM UTC by IvanTheBeara 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 IvanTheBeara 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:15PM UTC by dmethvin comment:4

#2901 is a duplicate of this ticket.

Changed November 13, 2010 07:20PM UTC by dmethvin comment:5

status: newopen

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:

http://www.w3.org/TR/selectors-api/#resolving-namespaces

Changed November 13, 2010 07:39PM UTC by dmethvin comment:6

#3404 is a duplicate of this ticket.

Changed April 16, 2011 09:29PM UTC by john comment:7

milestone: 1.2.2
resolution: → wontfix
status: openclosed

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!

Changed October 26, 2012 02:07PM UTC by dmethvin comment:8

#12787 is a duplicate of this ticket.