Side navigation
#8972 closed bug (invalid)
Opened April 25, 2011 06:08PM UTC
Closed April 26, 2011 02:12AM UTC
Last modified June 07, 2012 12:12PM UTC
HIERARCHY_REQUEST_ERROR(3) appending XHTML DIV into XHTML DIV on IE
Reported by: | jaraco | Owned by: | jaraco |
---|---|---|---|
Priority: | low | Milestone: | 1.next |
Component: | ajax | Version: | 1.5.2 |
Keywords: | xhtml | Cc: | |
Blocked by: | Blocking: |
Description
I originally created this post in the forums to better understand why I was unable to load an XHTML document element into another XHTML document node using jQuery 1.5.2 on IE. I've since concluded that to the best of my understanding, jQuery doesn't support loading an XHTML node into another XHTML document unless the new node is coerced into HTML (such as through the 'html' parameter to get).
It should be possible to load an XHTML document that has XML headers on it (such as a <!DOCTYPE> or preprocessing instruction) and add it (or a subnode) to another XHTML document. The following describes a simple example to reproduce the error.
Here's a harness with a script that performs a dynamic load of an XHTML file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.js" type="text/javascript"></script> <script type="text/javascript"> function load_stuff(widget_source, status, request) { var node = $(widget_source.documentElement).clone(); var target = $('#main_cont'); target.append(node); } // Load and init the widget $(document).ready(function() {$.get('widget.xhtml', load_stuff);}); </script> </head> <body> <div id="main_cont"> </div> </body> </html>
And widget.xhtml that it tries to load:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <div xmlns="http://www.w3.org/1999/xhtml" xmlns:other="http://example.com/other"> <other:foo /> Got it! </div>
The code works on Firefox 4 and Chrome, displaying "Got it!" in the document. On IE, however, it fails with the HIERARCHY_REQUEST_ERROR(3) during the .append call.
As I mentioned in the forum, I can make it work if I remove the <!DOCTYPE> and force HTML processing by passing 'html' to the .get call and remove the reference to 'documentElement'.
Attachments (0)
Change History (14)
Changed April 25, 2011 06:10PM UTC by comment:1
Changed April 25, 2011 06:44PM UTC by comment:2
component: | unfiled → ajax |
---|---|
priority: | undecided → low |
resolution: | → duplicate |
status: | new → closed |
Changed April 25, 2011 07:38PM UTC by comment:4
These are not duplicate tickets. They describe different errors and invoke different functions. In particular, in this ticket describes using the .get
method, which can load XML, and the error occurs when the content is loaded as XML. Furthermore, the resolution for #8941 does not resolve this issue.
In particular, there appears to be no way to load widget.xhtml as given above. It is valid XHTML, but cannot be loaded into the DOM using IE. The only way to make it work is to alter the content server side.
Please re-open this ticket, or close it as "won't fix" and give a reason why this use-case is invalid.
Changed April 25, 2011 08:22PM UTC by comment:5
You are using the same functions: ajax and domManip (which are the lower level functions for load/get and append/html respectively). And that is not valid XHTML. A div cannot have the xmlns attribute, cannot be placed outside of a body, and the other:foo element is undefined because you're in strict mode.
Changed April 25, 2011 09:46PM UTC by comment:6
You're right. My mistake. The XHTML doesn't conform strictly to XHTML.
I get the same error if widget.xhtml is this code:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>A title</title> </head> <body> <div> Got it! </div> </body> </html>
I've updated the widgets.xhtml file and validated it at w3c. As a result of the change in structure, I've also updated harness.xhtml to get the correct node from the XHTML with
var node = $(widget_source).find('body div').clone();
I get the same error with the strictly-conforming XHTML file. This is because node is still an IXMLDomDocument2 and can't be appended to another div.
What's the proper way to load an XHTML document into another?
Changed April 25, 2011 10:51PM UTC by comment:7
resolution: | duplicate |
---|---|
status: | closed → reopened |
It shouldn't be different from html. That is interesting. Have you tried using http://api.jquery.com/load ? Load performs the insert by first attaching the given html to a disconnected div. This might solve the problem, but it's hard to know exactly. If you update your test case, I'll take another look.
Changed April 25, 2011 10:51PM UTC by comment:8
owner: | → jaraco |
---|---|
status: | reopened → pending |
Changed April 26, 2011 01:48AM UTC by comment:9
So widget_source
is text of an XML document? You're not supposed to try and parse XML with $()
, especially on IE, but you could try $.parseXML()
. That still leaves the problem of how to get XML nodes into an HTML document. Because no matter what you do, any IE before IE9 does not support XHTML. Or were you talking about IE9 here?
Do you have a test case?
Changed April 26, 2011 02:02AM UTC by comment:10
status: | pending → new |
---|
Replying to [comment:7 timmywil]:
Have you tried using http://api.jquery.com/load ?
If I try to use .load, I run into #8941 (which occurs even on Firefox 4). Here's an example that attempts to load the strict XHTML widget.xhtml (and included below for posterity).
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.js" type="text/javascript"></script> <script type="text/javascript"> // Load and init the widget $(document).ready(function (){$('#main_cont').load('widget.xhtml div');}); </script> </head> <body> <div id="main_cont"> </div> </body> </html>
Changed April 26, 2011 02:12AM UTC by comment:11
keywords: | → xhtml |
---|---|
resolution: | → invalid |
status: | new → closed |
Ok then. I looked into it a little more based on Dave's comment and if you are serving these files with Content-Type xhtml, they will not be supported in IE<9. Servers (especially static ones) will base the Content-Type off the file extension. My suggestion is to change your file extensions to .html and make sure they are being served with correct text/html header and they should load fine even with the xhtml DOCTYPE. Or, if you prefer, you can set your server to respond with an xhtml content-type only for user agents which support xhtml and html for the rest. At that point, your file extension will make no difference. Closing as I don't think this is an issue with jQuery.
Changed April 26, 2011 02:20AM UTC by comment:12
Replying to [comment:9 dmethvin]:
So widget_source
is text of an XML document?
I could have named the variable better. widget_source
is the result of the .get() call, which does some content-type detection. Since the source is of the type application/xhtml+xml
, widget_source
ends up being an IXMLDomDocument2 on IE9. On Firefox, it ends up being a vanilla Document, which is why .append() accepts it (or a clone at least).
That still leaves the problem of how to get XML nodes into an HTML document. Because no matter what you do, any IE before IE9 does not support XHTML. Or were you talking about IE9 here?
In the context of this bug, I am talking about IE9, though ultimately I need to support IE7 and preferably IE6. I do, though, want to use XHTML, because this is part of a componentized system where the components that are being loaded should be machine-readable and as structured as possible.
If it's the case that jQuery does not or cannot support loading XHTML in a cross-browser way (at this time), that is acceptable, but I need to reach that conclusion formally so I know I'm not just misinterpreting the usage.
All indications from the forums and bugs and common sense tell me this is possible without altering the widget source.
Do you have a test case?
Yes, the test case originally referenced does reproduce the problem in IE9.
Changed April 26, 2011 03:57AM UTC by comment:13
Sorry, I'm lazily coming up to speed. I missed the link in the original ticket and didn't read the forum post.
This isn't a limitation in jQuery, it's one in IE. The XML nodes can't be inserted into an HTML document. XML documents are pretty inflexible in IE, for example we can't add expando properties to IE's XML nodes either.
The technique you mentioned in your forum post is probably the solution you'll need to take. There's a reason why people prefer JSON to XML nowadays...
Changed June 07, 2012 12:12PM UTC by comment:14
Simple workaround by converting xml to string and then running with jquery, e.g.
function xml_to_string(xml_node) { if (xml_node.xml) return xml_node.xml; else if (XMLSerializer) { var xml_serializer = new XMLSerializer(); return xml_serializer.serializeToString(xml_node); } else { alert("ERROR: Extremely old browser"); return ""; } }
Usage:
$.get('some_xml_data.xml', function(data) { $('#the-element').append($(xml_to_string(data))); });
The examples as described above will be hosted here for some time.