Consider this:
<!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>
This script should load text.xml when the document has been loaded. text.xml looks like this:
<xml xmlns:atom="http://www.w3.org/2005/Atom">
<atom:x>Text</atom:x>
</xml>
When this file has been loaded, the text contents of the atom:x
-node are appended to the document. I can see "Text" in my browser window.
This works as expected in Firefox. However, it does not work in Opera unless I change the query from 'atom\\:x'
to just 'x'
. In this case it works in Opera, but not Firefox.
I have discovered a workaround, namely changing the query to 'atom\\:x, x'
, but I would rather like to get to the bottom of this.
Now for the funny twist: I can inline the xml directly instead of getting it from XHR by changing
var xml = $(xhr.responseXML);
into
var xml = $('<xml xmlns:atom="http://www.w3.org/2005/Atom"><atom:x>Text</atom:x></xml>');
In this case a query of 'atom\\:x'
will give the desired result in both browsers and just 'x'
will give no result in both browsers.
The fact that this works differently in Opera leads me to conclude that the former behavior is a bug in Opera. Is this a reasonable conclusion? Where can I point to for the standard that describes how this is supposed to work?
In conclusion:
Hope you can help :)
It's not a bug in Opera. It's the correct behavior:
In a namespace-aware client, the name part of element type selectors (the part after the namespace separator, if it is present) will only match against the local part of the element's qualified name.
In your case local name is x
, and atom:x
isn't even a legal local name in XML.
Moreover, namespace-prefixed type selector in CSS has different syntax that doesn't use colon at all:
@namespace atom url(http://www.w3.org/2005/Atom);
atom|x { color: blue }
Your syntax seems to rely on a quirk introduced by HTML parsers in namespace-unaware user-agents.
HTML parser "eats" the colon as part of tag name and you get atom:x
element in default namespace, which would match atom\:x
selector, but in XML that you get x
element in http://www.w3.org/2005/Atom
namespace.
I've already experienced this behavior in different versions of the same browser and as far as I remember at the time I was testing the problematic page with FF and IE, so I'd say it's not an Opera-specific bug.
I'd suggest that whenever you use jQuery for parsing XML tags with namespace prefixes, you query for the selector both with and without the prefix. That is, instead of using
var x_txt = xml.find('atom\\:x').text();
try
var x_txt = xml.find('atom\\:x, x').text();
I think this is an acceptable workaround for most situations and it will assure that your results are correct despite the misbehaviors...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With