Skip to main content

Bug Tracker

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

The examples as described above will be hosted here for some time.

Changed April 25, 2011 06:44PM UTC by timmywil comment:2

component: unfiledajax
priority: undecidedlow
resolution: → duplicate
status: newclosed

Changed April 25, 2011 06:44PM UTC by timmywil comment:3

Duplicate of #8941.

Changed April 25, 2011 07:38PM UTC by jaraco 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 timmywil 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 jaraco 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 timmywil comment:7

resolution: duplicate
status: closedreopened

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 timmywil comment:8

owner: → jaraco
status: reopenedpending

Changed April 26, 2011 01:48AM UTC by dmethvin 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 jaraco comment:10

status: pendingnew

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 timmywil comment:11

keywords: → xhtml
resolution: → invalid
status: newclosed

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 jaraco 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 dmethvin 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 mudyc 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)));
});